@principal-ai/file-city-react 0.5.23 → 0.5.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ArchitectureMapHighlightLayers.d.ts +6 -2
- package/dist/components/ArchitectureMapHighlightLayers.d.ts.map +1 -1
- package/dist/components/ArchitectureMapHighlightLayers.js +74 -2
- package/dist/components/FileCity3D/FileCity3D.d.ts +18 -1
- package/dist/components/FileCity3D/FileCity3D.d.ts.map +1 -1
- package/dist/components/FileCity3D/FileCity3D.js +99 -58
- package/dist/components/FileCity3D/index.d.ts +2 -2
- package/dist/components/FileCity3D/index.d.ts.map +1 -1
- package/dist/components/FileCity3D/index.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/stories/sample-data.d.ts.map +1 -1
- package/dist/stories/sample-data.js +44 -42
- package/dist/utils/visualizationResolution.d.ts +72 -0
- package/dist/utils/visualizationResolution.d.ts.map +1 -0
- package/dist/utils/visualizationResolution.js +100 -0
- package/package.json +1 -1
- package/src/components/ArchitectureMapHighlightLayers.tsx +101 -2
- package/src/components/FileCity3D/FileCity3D.tsx +145 -77
- package/src/components/FileCity3D/index.ts +2 -0
- package/src/index.ts +10 -1
- package/src/stories/2D3DComparison.stories.tsx +527 -0
- package/src/stories/sample-data.ts +47 -45
- package/src/utils/visualizationResolution.ts +170 -0
|
@@ -59,9 +59,13 @@ export interface ArchitectureMapHighlightLayersProps {
|
|
|
59
59
|
}) => void;
|
|
60
60
|
buildingBorderRadius?: number;
|
|
61
61
|
districtBorderRadius?: number;
|
|
62
|
+
/** Color to highlight the focused directory border (hex color, e.g. "#3b82f6") */
|
|
63
|
+
focusColor?: string | null;
|
|
64
|
+
/** Base file type color layers (resolved with highlightLayers) */
|
|
65
|
+
fileColorLayers?: HighlightLayer[];
|
|
62
66
|
}
|
|
63
|
-
declare function ArchitectureMapHighlightLayersInner({ cityData, highlightLayers, onLayerToggle, focusDirectory, rootDirectoryName, onDirectorySelect, onFileClick, enableZoom, zoomToPath, onZoomComplete, zoomAnimationSpeed, allowZoomToPath, fullSize, showGrid, showFileNames, className, selectiveRender, canvasBackgroundColor, maxCanvasSize, hoverBorderColor, disableOpacityDimming, defaultDirectoryColor, defaultBuildingColor, subdirectoryMode, showLayerControls, showFileTypeIcons, showDirectoryLabels, transform, // Default to no rotation
|
|
64
|
-
onHover, buildingBorderRadius, districtBorderRadius, }: ArchitectureMapHighlightLayersProps): import("react/jsx-runtime").JSX.Element;
|
|
67
|
+
declare function ArchitectureMapHighlightLayersInner({ cityData, highlightLayers: externalHighlightLayers, onLayerToggle, focusDirectory, rootDirectoryName, onDirectorySelect, onFileClick, enableZoom, zoomToPath: externalZoomToPath, onZoomComplete, zoomAnimationSpeed, allowZoomToPath, fullSize, showGrid, showFileNames, className, selectiveRender, canvasBackgroundColor, maxCanvasSize, hoverBorderColor, disableOpacityDimming, defaultDirectoryColor, defaultBuildingColor, subdirectoryMode, showLayerControls, showFileTypeIcons, showDirectoryLabels, transform, // Default to no rotation
|
|
68
|
+
onHover, buildingBorderRadius, districtBorderRadius, focusColor: externalFocusColor, fileColorLayers, }: ArchitectureMapHighlightLayersProps): import("react/jsx-runtime").JSX.Element;
|
|
65
69
|
export declare const ArchitectureMapHighlightLayers: typeof ArchitectureMapHighlightLayersInner;
|
|
66
70
|
export {};
|
|
67
71
|
//# sourceMappingURL=ArchitectureMapHighlightLayers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArchitectureMapHighlightLayers.d.ts","sourceRoot":"","sources":["../../src/components/ArchitectureMapHighlightLayers.tsx"],"names":[],"mappings":"AAQA,OAAO,EAIL,cAAc,EAGf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACvB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"ArchitectureMapHighlightLayers.d.ts","sourceRoot":"","sources":["../../src/components/ArchitectureMapHighlightLayers.tsx"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { filterCityDataForSelectiveRender, filterCityDataForSubdirectory, filter
|
|
|
5
5
|
import { drawLayeredBuildings, drawLayeredDistricts, drawGrid, LayerIndex, } from '../render/client/drawLayeredBuildings';
|
|
6
6
|
import { getDefaultFileColorConfig } from '../utils/fileColorHighlightLayers';
|
|
7
7
|
import { extractIconConfig } from '../utils/fileTypeIcons';
|
|
8
|
+
import { resolveVisualizationIntent } from '../utils/visualizationResolution';
|
|
8
9
|
const DEFAULT_DISPLAY_OPTIONS = {
|
|
9
10
|
showGrid: false,
|
|
10
11
|
showConnections: true,
|
|
@@ -144,9 +145,41 @@ class PathHierarchyLookup {
|
|
|
144
145
|
return this.abstractedPaths.has(path);
|
|
145
146
|
}
|
|
146
147
|
}
|
|
147
|
-
function ArchitectureMapHighlightLayersInner({ cityData, highlightLayers
|
|
148
|
-
onHover, buildingBorderRadius = 0, districtBorderRadius = 0, }) {
|
|
148
|
+
function ArchitectureMapHighlightLayersInner({ cityData, highlightLayers: externalHighlightLayers, onLayerToggle, focusDirectory = null, rootDirectoryName, onDirectorySelect, onFileClick, enableZoom = false, zoomToPath: externalZoomToPath, onZoomComplete, zoomAnimationSpeed = 0.12, allowZoomToPath = true, fullSize = false, showGrid = false, showFileNames = false, className = '', selectiveRender, canvasBackgroundColor, maxCanvasSize, hoverBorderColor, disableOpacityDimming = true, defaultDirectoryColor, defaultBuildingColor, subdirectoryMode, showLayerControls = false, showFileTypeIcons = true, showDirectoryLabels = true, transform = { rotation: 0 }, // Default to no rotation
|
|
149
|
+
onHover, buildingBorderRadius = 0, districtBorderRadius = 0, focusColor: externalFocusColor, fileColorLayers, }) {
|
|
149
150
|
const { theme } = useTheme();
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// Visualization Resolution
|
|
153
|
+
// Always resolve: combines highlightLayers with fileColorLayers,
|
|
154
|
+
// filtering fileColorLayers based on focus/highlight scope.
|
|
155
|
+
// ============================================================================
|
|
156
|
+
const resolved = useMemo(() => {
|
|
157
|
+
// Cast to InputHighlightLayer[] for resolution - types are compatible at runtime
|
|
158
|
+
const resolution = resolveVisualizationIntent({
|
|
159
|
+
focusPath: externalZoomToPath,
|
|
160
|
+
focusColor: externalFocusColor,
|
|
161
|
+
highlightLayers: (externalHighlightLayers ?? []),
|
|
162
|
+
fileColorLayers: (fileColorLayers ?? []),
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
highlightLayers: resolution.highlightLayers,
|
|
166
|
+
zoomToPath: resolution.cameraFocusPath,
|
|
167
|
+
focusColor: resolution.focusColor,
|
|
168
|
+
shouldDim: resolution.shouldIsolate,
|
|
169
|
+
};
|
|
170
|
+
}, [
|
|
171
|
+
fileColorLayers,
|
|
172
|
+
externalHighlightLayers,
|
|
173
|
+
externalZoomToPath,
|
|
174
|
+
externalFocusColor,
|
|
175
|
+
]);
|
|
176
|
+
// Use resolved values, ensuring layers have required priority for drawing functions
|
|
177
|
+
const highlightLayers = useMemo(() => resolved.highlightLayers.map((layer, index) => ({
|
|
178
|
+
...layer,
|
|
179
|
+
priority: layer.priority ?? index,
|
|
180
|
+
})), [resolved.highlightLayers]);
|
|
181
|
+
const zoomToPath = resolved.zoomToPath;
|
|
182
|
+
const focusColor = resolved.focusColor;
|
|
150
183
|
// Use theme colors as defaults, with prop overrides
|
|
151
184
|
const resolvedCanvasBackgroundColor = canvasBackgroundColor ?? theme.colors.background;
|
|
152
185
|
const resolvedHoverBorderColor = hoverBorderColor ?? theme.colors.text;
|
|
@@ -814,6 +847,42 @@ onHover, buildingBorderRadius = 0, districtBorderRadius = 0, }) {
|
|
|
814
847
|
// Draw buildings with layer support
|
|
815
848
|
drawLayeredBuildings(ctx, visibleBuildingsMemo, worldToCanvas, scale * zoomState.scale, allLayers, interactionState.hoveredBuilding, resolvedDefaultBuildingColor, showFileNames, resolvedHoverBorderColor, disableOpacityDimming, showFileTypeIcons, buildingBorderRadius, layerIndex, // Pre-built index for O(1) lookups
|
|
816
849
|
iconMap);
|
|
850
|
+
// Draw focus color border around the zoomToPath target
|
|
851
|
+
if (focusColor && zoomToPath) {
|
|
852
|
+
const normalizedPath = zoomToPath.replace(/^\/+|\/+$/g, '');
|
|
853
|
+
// Find the district or building that matches the path
|
|
854
|
+
const targetDistrict = filteredCityData.districts?.find(d => d.path === normalizedPath || d.path === zoomToPath);
|
|
855
|
+
const targetBuilding = !targetDistrict
|
|
856
|
+
? filteredCityData.buildings?.find(b => b.path === normalizedPath || b.path === zoomToPath)
|
|
857
|
+
: null;
|
|
858
|
+
if (targetDistrict) {
|
|
859
|
+
// Draw border around district
|
|
860
|
+
const { minX, maxX, minZ, maxZ } = targetDistrict.worldBounds;
|
|
861
|
+
const topLeft = worldToCanvas(minX, minZ);
|
|
862
|
+
const bottomRight = worldToCanvas(maxX, maxZ);
|
|
863
|
+
const width = bottomRight.x - topLeft.x;
|
|
864
|
+
const height = bottomRight.y - topLeft.y;
|
|
865
|
+
ctx.save();
|
|
866
|
+
ctx.strokeStyle = focusColor;
|
|
867
|
+
ctx.lineWidth = 3 * zoomState.scale;
|
|
868
|
+
ctx.strokeRect(topLeft.x, topLeft.y, width, height);
|
|
869
|
+
ctx.restore();
|
|
870
|
+
}
|
|
871
|
+
else if (targetBuilding) {
|
|
872
|
+
// Draw border around building
|
|
873
|
+
const size = Math.max(targetBuilding.dimensions[0], targetBuilding.dimensions[2]);
|
|
874
|
+
const halfSize = size / 2;
|
|
875
|
+
const topLeft = worldToCanvas(targetBuilding.position.x - halfSize, targetBuilding.position.z - halfSize);
|
|
876
|
+
const bottomRight = worldToCanvas(targetBuilding.position.x + halfSize, targetBuilding.position.z + halfSize);
|
|
877
|
+
const width = bottomRight.x - topLeft.x;
|
|
878
|
+
const height = bottomRight.y - topLeft.y;
|
|
879
|
+
ctx.save();
|
|
880
|
+
ctx.strokeStyle = focusColor;
|
|
881
|
+
ctx.lineWidth = 3 * zoomState.scale;
|
|
882
|
+
ctx.strokeRect(topLeft.x, topLeft.y, width, height);
|
|
883
|
+
ctx.restore();
|
|
884
|
+
}
|
|
885
|
+
}
|
|
817
886
|
// Performance monitoring end available for debugging
|
|
818
887
|
// Performance stats available but not logged to reduce console noise
|
|
819
888
|
// Uncomment for debugging: render time, buildings/districts counts, layer counts
|
|
@@ -848,6 +917,9 @@ onHover, buildingBorderRadius = 0, districtBorderRadius = 0, }) {
|
|
|
848
917
|
abstractedPathsSet,
|
|
849
918
|
layerIndex,
|
|
850
919
|
iconMap,
|
|
920
|
+
// Focus color border
|
|
921
|
+
focusColor,
|
|
922
|
+
zoomToPath,
|
|
851
923
|
]);
|
|
852
924
|
// Optimized hit testing
|
|
853
925
|
const performHitTest = useCallback((canvasX, canvasY) => {
|
|
@@ -29,6 +29,10 @@ export interface HighlightLayer {
|
|
|
29
29
|
items: HighlightItem[];
|
|
30
30
|
/** Opacity for highlighted items (0-1) */
|
|
31
31
|
opacity?: number;
|
|
32
|
+
/** Rendering priority (higher renders on top) */
|
|
33
|
+
priority?: number;
|
|
34
|
+
/** Border width in pixels */
|
|
35
|
+
borderWidth?: number;
|
|
32
36
|
}
|
|
33
37
|
export interface HighlightItem {
|
|
34
38
|
/** File or directory path */
|
|
@@ -54,6 +58,15 @@ export interface AnimationConfig {
|
|
|
54
58
|
}
|
|
55
59
|
/** Height scaling mode for buildings */
|
|
56
60
|
export type HeightScaling = 'logarithmic' | 'linear';
|
|
61
|
+
/** Pattern for files that should render flat (e.g., lock files, generated files) */
|
|
62
|
+
export interface FlatPattern {
|
|
63
|
+
/** Glob-like pattern or regex to match file paths */
|
|
64
|
+
pattern: string | RegExp;
|
|
65
|
+
/** Height to use for matched files (default: 0.5) */
|
|
66
|
+
height?: number;
|
|
67
|
+
}
|
|
68
|
+
/** Default patterns for files that should render flat */
|
|
69
|
+
export declare const DEFAULT_FLAT_PATTERNS: FlatPattern[];
|
|
57
70
|
export interface RotateOptions {
|
|
58
71
|
/** Animation duration in milliseconds. Default uses spring physics (~800ms feel). */
|
|
59
72
|
duration?: number;
|
|
@@ -156,6 +169,8 @@ export interface FileCity3DProps {
|
|
|
156
169
|
heightScaling?: HeightScaling;
|
|
157
170
|
/** Scale factor for linear mode (height per line, default 0.05) */
|
|
158
171
|
linearScale?: number;
|
|
172
|
+
/** Patterns for files that should render flat (e.g., lock files). Set to DEFAULT_FLAT_PATTERNS for common lock files, or [] to disable. */
|
|
173
|
+
flatPatterns?: FlatPattern[];
|
|
159
174
|
/** Directory path to focus on - buildings outside will collapse */
|
|
160
175
|
focusDirectory?: string | null;
|
|
161
176
|
/** Color to highlight the focused directory (hex color, e.g. "#3b82f6") */
|
|
@@ -170,6 +185,8 @@ export interface FileCity3DProps {
|
|
|
170
185
|
selectedBuilding?: CityBuilding | null;
|
|
171
186
|
/** When true, camera height adjusts based on tallest building when grown */
|
|
172
187
|
adaptCameraToBuildings?: boolean;
|
|
188
|
+
/** Base file type color layers (resolved with highlightLayers) */
|
|
189
|
+
fileColorLayers?: HighlightLayer[];
|
|
173
190
|
}
|
|
174
191
|
/**
|
|
175
192
|
* FileCity3D - 3D visualization of codebase structure
|
|
@@ -177,6 +194,6 @@ export interface FileCity3DProps {
|
|
|
177
194
|
* Renders CityData as an interactive 3D city where buildings represent files
|
|
178
195
|
* and their height corresponds to line count or file size.
|
|
179
196
|
*/
|
|
180
|
-
export declare function FileCity3D({ cityData, width, height, onBuildingClick, className, style, animation, isGrown: externalIsGrown, onGrowChange, showControls, highlightLayers, isolationMode, dimOpacity: _dimOpacity, isLoading, loadingMessage, emptyMessage, heightScaling, linearScale, focusDirectory, focusColor, onDirectorySelect: _onDirectorySelect, backgroundColor, textColor, selectedBuilding, adaptCameraToBuildings, }: FileCity3DProps): import("react/jsx-runtime").JSX.Element;
|
|
197
|
+
export declare function FileCity3D({ cityData, width, height, onBuildingClick, className, style, animation, isGrown: externalIsGrown, onGrowChange, showControls, highlightLayers: externalHighlightLayers, isolationMode: externalIsolationMode, dimOpacity: _dimOpacity, isLoading, loadingMessage, emptyMessage, heightScaling, linearScale, flatPatterns, focusDirectory: externalFocusDirectory, focusColor: externalFocusColor, onDirectorySelect: _onDirectorySelect, backgroundColor, textColor, selectedBuilding, adaptCameraToBuildings, fileColorLayers, }: FileCity3DProps): import("react/jsx-runtime").JSX.Element;
|
|
181
198
|
export default FileCity3D;
|
|
182
199
|
//# sourceMappingURL=FileCity3D.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileCity3D.d.ts","sourceRoot":"","sources":["../../../src/components/FileCity3D/FileCity3D.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAA4D,MAAM,OAAO,CAAC;AAMjF,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EAEb,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"FileCity3D.d.ts","sourceRoot":"","sources":["../../../src/components/FileCity3D/FileCity3D.tsx"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,31 @@ import { useSpring } from '@react-spring/three';
|
|
|
13
13
|
import { OrbitControls, PerspectiveCamera, Text } from '@react-three/drei';
|
|
14
14
|
import { getFileConfig } from '@principal-ai/file-city-builder';
|
|
15
15
|
import * as THREE from 'three';
|
|
16
|
+
import { resolveVisualizationIntent } from '../../utils/visualizationResolution';
|
|
17
|
+
/** Default patterns for files that should render flat */
|
|
18
|
+
export const DEFAULT_FLAT_PATTERNS = [
|
|
19
|
+
{ pattern: /package-lock\.json$/ },
|
|
20
|
+
{ pattern: /yarn\.lock$/ },
|
|
21
|
+
{ pattern: /pnpm-lock\.yaml$/ },
|
|
22
|
+
{ pattern: /composer\.lock$/ },
|
|
23
|
+
{ pattern: /Gemfile\.lock$/ },
|
|
24
|
+
{ pattern: /Cargo\.lock$/ },
|
|
25
|
+
{ pattern: /poetry\.lock$/ },
|
|
26
|
+
{ pattern: /\.lock$/ }, // Generic lock files
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Check if a file path matches any flat pattern.
|
|
30
|
+
* Returns the matched pattern's height or undefined if no match.
|
|
31
|
+
*/
|
|
32
|
+
function matchFlatPattern(path, patterns) {
|
|
33
|
+
for (const { pattern, height } of patterns) {
|
|
34
|
+
const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
|
|
35
|
+
if (regex.test(path)) {
|
|
36
|
+
return height ?? 0.5; // Default flat height
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
16
41
|
const DEFAULT_ANIMATION = {
|
|
17
42
|
startFlat: false,
|
|
18
43
|
autoStartDelay: 500,
|
|
@@ -26,7 +51,12 @@ const DEFAULT_ANIMATION = {
|
|
|
26
51
|
* - logarithmic: Compresses large values (default, good for mixed codebases)
|
|
27
52
|
* - linear: Direct scaling (1 line = linearScale units of height)
|
|
28
53
|
*/
|
|
29
|
-
function calculateBuildingHeight(building, scaling = 'logarithmic', linearScale =
|
|
54
|
+
function calculateBuildingHeight(building, scaling = 'logarithmic', linearScale = 1, flatPatterns = []) {
|
|
55
|
+
// Check if this file matches a flat pattern (e.g., lock files)
|
|
56
|
+
const flatHeight = matchFlatPattern(building.path, flatPatterns);
|
|
57
|
+
if (flatHeight !== undefined) {
|
|
58
|
+
return flatHeight;
|
|
59
|
+
}
|
|
30
60
|
const minHeight = 2;
|
|
31
61
|
// Use lineCount if available (any text file), otherwise fall back to size
|
|
32
62
|
if (building.lineCount !== undefined) {
|
|
@@ -209,7 +239,7 @@ function isPathInDirectory(path, directory) {
|
|
|
209
239
|
return true;
|
|
210
240
|
return path === directory || path.startsWith(directory + '/');
|
|
211
241
|
}
|
|
212
|
-
function InstancedBuildings({ buildings, centerOffset, onHover, onClick, hoveredIndex, selectedIndex, growProgress, animationConfig, heightScaling, linearScale, staggerIndices, focusDirectory, highlightLayers, isolationMode, }) {
|
|
242
|
+
function InstancedBuildings({ buildings, centerOffset, onHover, onClick, hoveredIndex, selectedIndex, growProgress, animationConfig, heightScaling, linearScale, flatPatterns, staggerIndices, focusDirectory, highlightLayers, isolationMode, }) {
|
|
213
243
|
const meshRef = useRef(null);
|
|
214
244
|
const startTimeRef = useRef(null);
|
|
215
245
|
const tempObject = useMemo(() => new THREE.Object3D(), []);
|
|
@@ -282,8 +312,10 @@ function InstancedBuildings({ buildings, centerOffset, onHover, onClick, hovered
|
|
|
282
312
|
const buildingData = useMemo(() => {
|
|
283
313
|
return buildings.map((building, index) => {
|
|
284
314
|
const [width, , depth] = building.dimensions;
|
|
285
|
-
const fullHeight = calculateBuildingHeight(building, heightScaling, linearScale);
|
|
286
|
-
|
|
315
|
+
const fullHeight = calculateBuildingHeight(building, heightScaling, linearScale, flatPatterns);
|
|
316
|
+
// Use highlight layer color if available, otherwise fall back to file config color
|
|
317
|
+
const highlight = getHighlightForPath(building.path, highlightLayers);
|
|
318
|
+
const color = highlight?.color ?? getColorForFile(building);
|
|
287
319
|
const x = building.position.x - centerOffset.x;
|
|
288
320
|
const z = building.position.z - centerOffset.z;
|
|
289
321
|
const staggerIndex = staggerIndices[index] ?? index;
|
|
@@ -305,8 +337,10 @@ function InstancedBuildings({ buildings, centerOffset, onHover, onClick, hovered
|
|
|
305
337
|
centerOffset,
|
|
306
338
|
heightScaling,
|
|
307
339
|
linearScale,
|
|
340
|
+
flatPatterns,
|
|
308
341
|
staggerIndices,
|
|
309
342
|
animationConfig.staggerDelay,
|
|
343
|
+
highlightLayers,
|
|
310
344
|
]);
|
|
311
345
|
const minHeight = 0.3;
|
|
312
346
|
const baseOffset = 0.2;
|
|
@@ -428,7 +462,7 @@ function InstancedBuildings({ buildings, centerOffset, onHover, onClick, hovered
|
|
|
428
462
|
}, [buildingData, onClick]);
|
|
429
463
|
if (buildingData.length === 0)
|
|
430
464
|
return null;
|
|
431
|
-
return (_jsxs("group", { children: [_jsxs("instancedMesh", { ref: meshRef, args: [undefined, undefined, buildingData.length], onPointerMove: handlePointerMove, onPointerOut: handlePointerOut, onClick: handleClick, frustumCulled: false, children: [_jsx("boxGeometry", { args: [1, 1, 1] }), _jsx("
|
|
465
|
+
return (_jsxs("group", { children: [_jsxs("instancedMesh", { ref: meshRef, args: [undefined, undefined, buildingData.length], onPointerMove: handlePointerMove, onPointerOut: handlePointerOut, onClick: handleClick, frustumCulled: false, children: [_jsx("boxGeometry", { args: [1, 1, 1] }), _jsx("meshBasicMaterial", {})] }), _jsx(BuildingEdges, { buildings: buildingData.map(d => ({
|
|
432
466
|
width: d.width,
|
|
433
467
|
depth: d.depth,
|
|
434
468
|
fullHeight: d.fullHeight,
|
|
@@ -466,17 +500,13 @@ function AnimatedIcon({ x, z, targetHeight, iconSize, texture, opacity, growProg
|
|
|
466
500
|
const height = animProgress * targetHeight + minHeight;
|
|
467
501
|
const buildingTop = height + baseOffset;
|
|
468
502
|
// When flat (animProgress=0): icon lies flat at ground level
|
|
469
|
-
// When grown (animProgress=1): icon
|
|
470
|
-
const flatY = minHeight + baseOffset + 0.
|
|
471
|
-
const grownY = buildingTop +
|
|
503
|
+
// When grown (animProgress=1): icon lies flat on building roof
|
|
504
|
+
const flatY = minHeight + baseOffset + 0.1;
|
|
505
|
+
const grownY = buildingTop + 0.1;
|
|
472
506
|
const yPosition = flatY + (grownY - flatY) * animProgress;
|
|
473
507
|
meshRef.current.position.y = yPosition;
|
|
474
|
-
//
|
|
475
|
-
|
|
476
|
-
// Grown: 0 (facing forward)
|
|
477
|
-
const flatRotationX = -Math.PI / 2;
|
|
478
|
-
const grownRotationX = 0;
|
|
479
|
-
meshRef.current.rotation.x = flatRotationX + (grownRotationX - flatRotationX) * animProgress;
|
|
508
|
+
// Keep icon flat (facing up) at all times
|
|
509
|
+
meshRef.current.rotation.x = -Math.PI / 2;
|
|
480
510
|
if (materialRef.current) {
|
|
481
511
|
// Show icons even when flat, fade out only slightly
|
|
482
512
|
const minOpacity = 0.8;
|
|
@@ -486,7 +516,7 @@ function AnimatedIcon({ x, z, targetHeight, iconSize, texture, opacity, growProg
|
|
|
486
516
|
});
|
|
487
517
|
return (_jsxs("mesh", { ref: meshRef, position: [x, 0, z], scale: [iconSize, iconSize, 1], raycast: () => null, children: [_jsx("planeGeometry", { args: [1, 1] }), _jsx("meshBasicMaterial", { ref: materialRef, map: texture, transparent: true, opacity: 0.8, depthTest: true, depthWrite: false, side: THREE.DoubleSide })] }));
|
|
488
518
|
}
|
|
489
|
-
function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, linearScale, highlightLayers, isolationMode, hasActiveHighlights, staggerIndices, springDuration, staggerDelay, }) {
|
|
519
|
+
function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, linearScale, flatPatterns, highlightLayers, isolationMode, hasActiveHighlights, staggerIndices, springDuration, staggerDelay, }) {
|
|
490
520
|
// Pre-compute buildings with icons
|
|
491
521
|
const buildingsWithIcons = useMemo(() => {
|
|
492
522
|
return buildings
|
|
@@ -501,7 +531,7 @@ function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, l
|
|
|
501
531
|
const shouldCollapse = shouldDim && isolationMode === 'collapse';
|
|
502
532
|
if (shouldHide)
|
|
503
533
|
return null;
|
|
504
|
-
const fullHeight = calculateBuildingHeight(building, heightScaling, linearScale);
|
|
534
|
+
const fullHeight = calculateBuildingHeight(building, heightScaling, linearScale, flatPatterns);
|
|
505
535
|
const targetHeight = shouldCollapse ? 0.5 : fullHeight;
|
|
506
536
|
const x = building.position.x - centerOffset.x;
|
|
507
537
|
const z = building.position.z - centerOffset.z;
|
|
@@ -526,6 +556,7 @@ function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, l
|
|
|
526
556
|
hasActiveHighlights,
|
|
527
557
|
heightScaling,
|
|
528
558
|
linearScale,
|
|
559
|
+
flatPatterns,
|
|
529
560
|
staggerIndices,
|
|
530
561
|
staggerDelay,
|
|
531
562
|
]);
|
|
@@ -535,11 +566,10 @@ function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, l
|
|
|
535
566
|
const texture = getIconTexture(icon.name, icon.color || '#ffffff');
|
|
536
567
|
if (!texture)
|
|
537
568
|
return null;
|
|
538
|
-
// Icon size based on building dimensions
|
|
539
|
-
const [width] = building.dimensions;
|
|
540
|
-
const
|
|
541
|
-
const
|
|
542
|
-
const iconSize = (baseSize + heightBoost) * (icon.size || 1);
|
|
569
|
+
// Icon size based on building dimensions (matching 2D calculation)
|
|
570
|
+
const [width, , depth] = building.dimensions;
|
|
571
|
+
const minDimension = Math.min(width, depth);
|
|
572
|
+
const iconSize = minDimension * (icon.size || 0.6) * 1.7;
|
|
543
573
|
const opacity = shouldDim && isolationMode === 'transparent' ? 0.3 : 1;
|
|
544
574
|
return (_jsx(AnimatedIcon, { x: x, z: z, targetHeight: targetHeight, iconSize: iconSize, texture: texture, opacity: opacity, growProgress: growProgress, staggerDelayMs: staggerDelayMs, springDuration: springDuration }, building.path));
|
|
545
575
|
}) }));
|
|
@@ -565,10 +595,10 @@ function DistrictFloor({ district, centerOffset, highlightColor, growProgress })
|
|
|
565
595
|
const flatY = 0.5;
|
|
566
596
|
const grownY = 1.5;
|
|
567
597
|
const textY = flatY + (grownY - flatY) * growProgress;
|
|
568
|
-
const flatZ =
|
|
569
|
-
const grownZ = depth / 2 + 2; //
|
|
598
|
+
const flatZ = depth / 2 - 6; // Near bottom of district when flat, with padding
|
|
599
|
+
const grownZ = depth / 2 + 2; // Just outside edge when grown
|
|
570
600
|
const textZ = flatZ + (grownZ - flatZ) * growProgress;
|
|
571
|
-
return (_jsxs("group", { position: [centerX, 0, centerZ], children: [_jsxs("lineSegments", { rotation: [-Math.PI / 2, 0, 0], position: [0, floorY, 0], renderOrder: -1, children: [_jsx("edgesGeometry", { args: [new THREE.PlaneGeometry(width, depth)], attach: "geometry" }), _jsx("lineBasicMaterial", { color: borderColor, linewidth: lineWidth, depthWrite: false })] }), highlightColor && (_jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], position: [0, floorY - 0.1, 0], renderOrder: -2, children: [_jsx("planeGeometry", { args: [width, depth] }), _jsx("meshBasicMaterial", { color: highlightColor, transparent: true, opacity: 0.15, depthWrite: false })] })),
|
|
601
|
+
return (_jsxs("group", { position: [centerX, 0, centerZ], children: [_jsxs("lineSegments", { rotation: [-Math.PI / 2, 0, 0], position: [0, floorY, 0], renderOrder: -1, children: [_jsx("edgesGeometry", { args: [new THREE.PlaneGeometry(width, depth)], attach: "geometry" }), _jsx("lineBasicMaterial", { color: borderColor, linewidth: lineWidth, depthWrite: false })] }), highlightColor && (_jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], position: [0, floorY - 0.1, 0], renderOrder: -2, children: [_jsx("planeGeometry", { args: [width, depth] }), _jsx("meshBasicMaterial", { color: highlightColor, transparent: true, opacity: 0.15, depthWrite: false })] })), _jsx(Text, { position: [0, textY, textZ], rotation: [textRotationX, 0, 0], fontSize: Math.max(6, Math.min(12, width / 3)), color: labelColor, anchorX: "center", anchorY: "middle", outlineWidth: 0.15, outlineColor: "#0f172a", children: dirName })] }));
|
|
572
602
|
}
|
|
573
603
|
let cameraApi = null;
|
|
574
604
|
export function resetCamera() {
|
|
@@ -656,6 +686,7 @@ function AnimatedCamera({ citySize, isFlat, focusTarget, maxBuildingHeight = 0 }
|
|
|
656
686
|
const frameCount = useRef(0);
|
|
657
687
|
// Calculate camera height to fit city in viewport (for top-down view)
|
|
658
688
|
// Formula: height = citySize / (2 * tan(fov/2) * min(1, aspect))
|
|
689
|
+
// Padding factor adds space around the city to match 2D component
|
|
659
690
|
const calculateFlatCameraHeight = useCallback(() => {
|
|
660
691
|
const perspCam = camera;
|
|
661
692
|
const fovRad = (perspCam.fov * Math.PI) / 180;
|
|
@@ -663,7 +694,10 @@ function AnimatedCamera({ citySize, isFlat, focusTarget, maxBuildingHeight = 0 }
|
|
|
663
694
|
const aspect = perspCam.aspect || 1;
|
|
664
695
|
// Use min(1, aspect) to handle both landscape and portrait viewports
|
|
665
696
|
const effectiveAspect = Math.min(1, aspect);
|
|
666
|
-
|
|
697
|
+
const baseHeight = citySize / (2 * tanHalfFov * effectiveAspect);
|
|
698
|
+
// Add padding to match 2D component's default padding
|
|
699
|
+
const paddingFactor = 1.08;
|
|
700
|
+
return baseHeight * paddingFactor;
|
|
667
701
|
}, [camera, citySize]);
|
|
668
702
|
// Compute target camera position
|
|
669
703
|
// When flat, always use top-down view (ignore focusTarget)
|
|
@@ -1125,7 +1159,7 @@ function ControlsOverlay({ isFlat, onToggle, onResetCamera }) {
|
|
|
1125
1159
|
gap: 8,
|
|
1126
1160
|
}, children: [_jsx("button", { onClick: onResetCamera, style: buttonStyle, children: "Reset View" }), _jsx("button", { onClick: onToggle, style: buttonStyle, children: isFlat ? 'Grow to 3D' : 'Flatten to 2D' })] }));
|
|
1127
1161
|
}
|
|
1128
|
-
function CityScene({ cityData, onBuildingHover, onBuildingClick, hoveredBuilding, selectedBuilding, growProgress, animationConfig, highlightLayers, isolationMode, heightScaling, linearScale, focusDirectory, focusColor, adaptCameraToBuildings = false, }) {
|
|
1162
|
+
function CityScene({ cityData, onBuildingHover, onBuildingClick, hoveredBuilding, selectedBuilding, growProgress, animationConfig, highlightLayers, isolationMode, heightScaling, linearScale, flatPatterns, focusDirectory, focusColor, adaptCameraToBuildings = false, }) {
|
|
1129
1163
|
const centerOffset = useMemo(() => ({
|
|
1130
1164
|
x: (cityData.bounds.minX + cityData.bounds.maxX) / 2,
|
|
1131
1165
|
z: (cityData.bounds.minZ + cityData.bounds.maxZ) / 2,
|
|
@@ -1257,37 +1291,11 @@ function CityScene({ cityData, onBuildingHover, onBuildingClick, hoveredBuilding
|
|
|
1257
1291
|
const size = Math.max(maxX - minX, maxZ - minZ);
|
|
1258
1292
|
return { x: centerX, z: centerZ, size };
|
|
1259
1293
|
}
|
|
1260
|
-
//
|
|
1261
|
-
|
|
1262
|
-
if (!activeHighlights || focusDirectory)
|
|
1263
|
-
return null;
|
|
1264
|
-
const highlightedBuildings = cityData.buildings.filter(building => {
|
|
1265
|
-
const highlight = getHighlightForPath(building.path, highlightLayers);
|
|
1266
|
-
return highlight !== null;
|
|
1267
|
-
});
|
|
1268
|
-
if (highlightedBuildings.length === 0)
|
|
1269
|
-
return null;
|
|
1270
|
-
let minX = Infinity, maxX = -Infinity;
|
|
1271
|
-
let minZ = Infinity, maxZ = -Infinity;
|
|
1272
|
-
for (const building of highlightedBuildings) {
|
|
1273
|
-
const x = building.position.x - centerOffset.x;
|
|
1274
|
-
const z = building.position.z - centerOffset.z;
|
|
1275
|
-
const [width, , depth] = building.dimensions;
|
|
1276
|
-
minX = Math.min(minX, x - width / 2);
|
|
1277
|
-
maxX = Math.max(maxX, x + width / 2);
|
|
1278
|
-
minZ = Math.min(minZ, z - depth / 2);
|
|
1279
|
-
maxZ = Math.max(maxZ, z + depth / 2);
|
|
1280
|
-
}
|
|
1281
|
-
const centerX = (minX + maxX) / 2;
|
|
1282
|
-
const centerZ = (minZ + maxZ) / 2;
|
|
1283
|
-
const size = Math.max(maxX - minX, maxZ - minZ);
|
|
1284
|
-
return { x: centerX, z: centerZ, size };
|
|
1294
|
+
// No auto-focus on highlights - camera only moves with explicit focusDirectory
|
|
1295
|
+
return null;
|
|
1285
1296
|
}, [
|
|
1286
1297
|
cameraFocusDirectory,
|
|
1287
|
-
focusDirectory,
|
|
1288
|
-
activeHighlights,
|
|
1289
1298
|
cityData.buildings,
|
|
1290
|
-
highlightLayers,
|
|
1291
1299
|
centerOffset,
|
|
1292
1300
|
isPathInDirectory,
|
|
1293
1301
|
]);
|
|
@@ -1342,7 +1350,7 @@ function CityScene({ cityData, onBuildingHover, onBuildingClick, hoveredBuilding
|
|
|
1342
1350
|
// Focus color takes priority, then highlight layer color
|
|
1343
1351
|
const districtColor = (isFocused && buildingFocusColor) ? buildingFocusColor : highlightLayerColor;
|
|
1344
1352
|
return (_jsx(DistrictFloor, { district: district, centerOffset: centerOffset, opacity: 1, highlightColor: districtColor, growProgress: growProgress }, district.path));
|
|
1345
|
-
}), _jsx(InstancedBuildings, { buildings: cityData.buildings, centerOffset: centerOffset, onHover: onBuildingHover, onClick: onBuildingClick, hoveredIndex: hoveredIndex, selectedIndex: selectedIndex, growProgress: growProgress, animationConfig: animationConfig, heightScaling: heightScaling, linearScale: linearScale, staggerIndices: staggerIndices, focusDirectory: buildingFocusDirectory, highlightLayers: highlightLayers, isolationMode: isolationMode }), _jsx(BuildingIcons, { buildings: cityData.buildings, centerOffset: centerOffset, growProgress: growProgress, heightScaling: heightScaling, linearScale: linearScale, highlightLayers: highlightLayers, isolationMode: isolationMode, hasActiveHighlights: activeHighlights, staggerIndices: staggerIndices, springDuration: springDuration, staggerDelay: animationConfig.staggerDelay || 15 })] }));
|
|
1353
|
+
}), _jsx(InstancedBuildings, { buildings: cityData.buildings, centerOffset: centerOffset, onHover: onBuildingHover, onClick: onBuildingClick, hoveredIndex: hoveredIndex, selectedIndex: selectedIndex, growProgress: growProgress, animationConfig: animationConfig, heightScaling: heightScaling, linearScale: linearScale, flatPatterns: flatPatterns, staggerIndices: staggerIndices, focusDirectory: buildingFocusDirectory, highlightLayers: highlightLayers, isolationMode: isolationMode }), _jsx(BuildingIcons, { buildings: cityData.buildings, centerOffset: centerOffset, growProgress: growProgress, heightScaling: heightScaling, linearScale: linearScale, flatPatterns: flatPatterns, highlightLayers: highlightLayers, isolationMode: isolationMode, hasActiveHighlights: activeHighlights, staggerIndices: staggerIndices, springDuration: springDuration, staggerDelay: animationConfig.staggerDelay || 15 })] }));
|
|
1346
1354
|
}
|
|
1347
1355
|
/**
|
|
1348
1356
|
* FileCity3D - 3D visualization of codebase structure
|
|
@@ -1350,10 +1358,42 @@ function CityScene({ cityData, onBuildingHover, onBuildingClick, hoveredBuilding
|
|
|
1350
1358
|
* Renders CityData as an interactive 3D city where buildings represent files
|
|
1351
1359
|
* and their height corresponds to line count or file size.
|
|
1352
1360
|
*/
|
|
1353
|
-
export function FileCity3D({ cityData, width = '100%', height = 600, onBuildingClick, className, style, animation, isGrown: externalIsGrown, onGrowChange, showControls = true, highlightLayers
|
|
1361
|
+
export function FileCity3D({ cityData, width = '100%', height = 600, onBuildingClick, className, style, animation, isGrown: externalIsGrown, onGrowChange, showControls = true, highlightLayers: externalHighlightLayers, isolationMode: externalIsolationMode, dimOpacity: _dimOpacity = 0.15, isLoading = false, loadingMessage = 'Loading file city...', emptyMessage = 'No file tree data available', heightScaling = 'linear', linearScale = 1, flatPatterns = DEFAULT_FLAT_PATTERNS, focusDirectory: externalFocusDirectory, focusColor: externalFocusColor, onDirectorySelect: _onDirectorySelect, backgroundColor = '#0f172a', textColor = '#94a3b8', selectedBuilding = null, adaptCameraToBuildings = false, fileColorLayers, }) {
|
|
1354
1362
|
const [hoveredBuilding, setHoveredBuilding] = useState(null);
|
|
1355
1363
|
const [internalIsGrown, setInternalIsGrown] = useState(false);
|
|
1356
1364
|
const animationConfig = useMemo(() => ({ ...DEFAULT_ANIMATION, ...animation }), [animation]);
|
|
1365
|
+
// ============================================================================
|
|
1366
|
+
// Visualization Resolution
|
|
1367
|
+
// Always resolve: combines highlightLayers with fileColorLayers,
|
|
1368
|
+
// filtering fileColorLayers based on focus/highlight scope.
|
|
1369
|
+
// ============================================================================
|
|
1370
|
+
const resolved = useMemo(() => {
|
|
1371
|
+
// Cast to InputHighlightLayer[] for resolution - types are compatible at runtime
|
|
1372
|
+
const resolution = resolveVisualizationIntent({
|
|
1373
|
+
focusPath: externalFocusDirectory,
|
|
1374
|
+
focusColor: externalFocusColor,
|
|
1375
|
+
highlightLayers: (externalHighlightLayers ?? []),
|
|
1376
|
+
fileColorLayers: (fileColorLayers ?? []),
|
|
1377
|
+
});
|
|
1378
|
+
return {
|
|
1379
|
+
highlightLayers: resolution.highlightLayers,
|
|
1380
|
+
focusDirectory: resolution.cameraFocusPath,
|
|
1381
|
+
focusColor: resolution.focusColor,
|
|
1382
|
+
// Use explicit isolation mode if provided, otherwise auto-determine
|
|
1383
|
+
isolationMode: externalIsolationMode ?? (resolution.shouldIsolate ? 'collapse' : 'none'),
|
|
1384
|
+
};
|
|
1385
|
+
}, [
|
|
1386
|
+
fileColorLayers,
|
|
1387
|
+
externalHighlightLayers,
|
|
1388
|
+
externalFocusDirectory,
|
|
1389
|
+
externalFocusColor,
|
|
1390
|
+
externalIsolationMode,
|
|
1391
|
+
]);
|
|
1392
|
+
// Use resolved values
|
|
1393
|
+
const highlightLayers = resolved.highlightLayers;
|
|
1394
|
+
const focusDirectory = resolved.focusDirectory;
|
|
1395
|
+
const focusColor = resolved.focusColor;
|
|
1396
|
+
const isolationMode = resolved.isolationMode;
|
|
1357
1397
|
const isGrown = externalIsGrown !== undefined ? externalIsGrown : internalIsGrown;
|
|
1358
1398
|
const setIsGrown = (value) => {
|
|
1359
1399
|
setInternalIsGrown(value);
|
|
@@ -1415,12 +1455,13 @@ export function FileCity3D({ cityData, width = '100%', height = 600, onBuildingC
|
|
|
1415
1455
|
background: backgroundColor,
|
|
1416
1456
|
overflow: 'hidden',
|
|
1417
1457
|
...style,
|
|
1418
|
-
}, children: [_jsx(Canvas, { shadows: true,
|
|
1458
|
+
}, children: [_jsx(Canvas, { shadows: true, flat // Disables tone mapping for true colors
|
|
1459
|
+
: true, style: {
|
|
1419
1460
|
position: 'absolute',
|
|
1420
1461
|
top: 0,
|
|
1421
1462
|
left: 0,
|
|
1422
1463
|
width: '100%',
|
|
1423
1464
|
height: '100%',
|
|
1424
|
-
}, children: _jsx(CityScene, { cityData: cityData, onBuildingHover: setHoveredBuilding, onBuildingClick: onBuildingClick, hoveredBuilding: hoveredBuilding, selectedBuilding: selectedBuilding, growProgress: growProgress, animationConfig: animationConfig, highlightLayers: highlightLayers, isolationMode: isolationMode, heightScaling: heightScaling, linearScale: linearScale, focusDirectory: focusDirectory, focusColor: focusColor, adaptCameraToBuildings: adaptCameraToBuildings }) }), _jsx(InfoPanel, { building: selectedBuilding || hoveredBuilding }), showControls && (_jsx(ControlsOverlay, { isFlat: !isGrown, onToggle: handleToggle, onResetCamera: resetCamera }))] }));
|
|
1465
|
+
}, children: _jsx(CityScene, { cityData: cityData, onBuildingHover: setHoveredBuilding, onBuildingClick: onBuildingClick, hoveredBuilding: hoveredBuilding, selectedBuilding: selectedBuilding, growProgress: growProgress, animationConfig: animationConfig, highlightLayers: highlightLayers, isolationMode: isolationMode, heightScaling: heightScaling, linearScale: linearScale, flatPatterns: flatPatterns, focusDirectory: focusDirectory, focusColor: focusColor, adaptCameraToBuildings: adaptCameraToBuildings }) }), _jsx(InfoPanel, { building: selectedBuilding || hoveredBuilding }), showControls && (_jsx(ControlsOverlay, { isFlat: !isGrown, onToggle: handleToggle, onResetCamera: resetCamera }))] }));
|
|
1425
1466
|
}
|
|
1426
1467
|
export default FileCity3D;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FileCity3D - 3D visualization component
|
|
3
3
|
*/
|
|
4
|
-
export { FileCity3D, resetCamera, getCameraAngle, getCameraTarget, getCameraTilt, rotateCameraTo, rotateCameraBy, tiltCameraTo, tiltCameraBy, moveCameraTo, setCameraTarget, } from './FileCity3D';
|
|
5
|
-
export type { FileCity3DProps, AnimationConfig, HighlightLayer, HighlightItem, IsolationMode, HeightScaling, CityData, CityBuilding, CityDistrict, } from './FileCity3D';
|
|
4
|
+
export { FileCity3D, resetCamera, getCameraAngle, getCameraTarget, getCameraTilt, rotateCameraTo, rotateCameraBy, tiltCameraTo, tiltCameraBy, moveCameraTo, setCameraTarget, DEFAULT_FLAT_PATTERNS, } from './FileCity3D';
|
|
5
|
+
export type { FileCity3DProps, AnimationConfig, HighlightLayer, HighlightItem, IsolationMode, HeightScaling, FlatPattern, CityData, CityBuilding, CityDistrict, } from './FileCity3D';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FileCity3D/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,UAAU,EACV,WAAW,EACX,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FileCity3D/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,UAAU,EACV,WAAW,EACX,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FileCity3D - 3D visualization component
|
|
3
3
|
*/
|
|
4
|
-
export { FileCity3D, resetCamera, getCameraAngle, getCameraTarget, getCameraTilt, rotateCameraTo, rotateCameraBy, tiltCameraTo, tiltCameraBy, moveCameraTo, setCameraTarget, } from './FileCity3D';
|
|
4
|
+
export { FileCity3D, resetCamera, getCameraAngle, getCameraTarget, getCameraTilt, rotateCameraTo, rotateCameraBy, tiltCameraTo, tiltCameraBy, moveCameraTo, setCameraTarget, DEFAULT_FLAT_PATTERNS, } from './FileCity3D';
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,9 @@ export type { UseCodeCityDataOptions, UseCodeCityDataReturn } from './hooks/useC
|
|
|
13
13
|
export type { FileTree } from '@principal-ai/file-city-builder';
|
|
14
14
|
export { CityViewWithReactFlow, type CityViewWithReactFlowProps, } from './components/CityViewWithReactFlow';
|
|
15
15
|
export { ThemeProvider, useTheme } from '@principal-ade/industry-theme';
|
|
16
|
-
export { FileCity3D, resetCamera } from './components/FileCity3D';
|
|
17
|
-
export type { FileCity3DProps, AnimationConfig, HighlightLayer as FileCity3DHighlightLayer, HighlightItem as FileCity3DHighlightItem, HighlightItem, IsolationMode, HeightScaling, } from './components/FileCity3D';
|
|
16
|
+
export { FileCity3D, resetCamera, DEFAULT_FLAT_PATTERNS } from './components/FileCity3D';
|
|
17
|
+
export type { FileCity3DProps, AnimationConfig, HighlightLayer as FileCity3DHighlightLayer, HighlightItem as FileCity3DHighlightItem, HighlightItem, IsolationMode, HeightScaling, FlatPattern, } from './components/FileCity3D';
|
|
18
18
|
export type { HighlightLayer as FileCity3DHL } from './components/FileCity3D';
|
|
19
|
+
export { resolveVisualizationIntent } from './utils/visualizationResolution';
|
|
20
|
+
export type { VisualizationIntent, ResolvedVisualizationState, } from './utils/visualizationResolution';
|
|
19
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,8BAA8B,EAC9B,KAAK,mCAAmC,GACzC,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,UAAU,GACX,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGvF,OAAO,EACL,gCAAgC,EAChC,6BAA6B,EAC7B,oCAAoC,GACrC,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,kCAAkC,CAAC;AAE1C,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGzF,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG7F,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACtB,QAAQ,EACR,UAAU,GACX,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAG7F,YAAY,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAGhE,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,GAChC,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAGxE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,8BAA8B,EAC9B,KAAK,mCAAmC,GACzC,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,UAAU,GACX,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGvF,OAAO,EACL,gCAAgC,EAChC,6BAA6B,EAC7B,oCAAoC,GACrC,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,kCAAkC,CAAC;AAE1C,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGzF,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG7F,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACtB,QAAQ,EACR,UAAU,GACX,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAG7F,YAAY,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAGhE,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,GAChC,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAGxE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACzF,YAAY,EACV,eAAe,EACf,eAAe,EACf,cAAc,IAAI,wBAAwB,EAC1C,aAAa,IAAI,uBAAuB,EACxC,aAAa,EACb,aAAa,EACb,aAAa,EACb,WAAW,GACZ,MAAM,yBAAyB,CAAC;AAIjC,YAAY,EAAE,cAAc,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAI9E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,YAAY,EACV,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,iCAAiC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -19,4 +19,7 @@ export { CityViewWithReactFlow, } from './components/CityViewWithReactFlow';
|
|
|
19
19
|
// Re-export theme utilities for consumers
|
|
20
20
|
export { ThemeProvider, useTheme } from '@principal-ade/industry-theme';
|
|
21
21
|
// 3D visualization component
|
|
22
|
-
export { FileCity3D, resetCamera } from './components/FileCity3D';
|
|
22
|
+
export { FileCity3D, resetCamera, DEFAULT_FLAT_PATTERNS } from './components/FileCity3D';
|
|
23
|
+
// Visualization resolution utilities
|
|
24
|
+
// See docs/VISUALIZATION_STATE_RESOLUTION.md for documentation
|
|
25
|
+
export { resolveVisualizationIntent } from './utils/visualizationResolution';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sample-data.d.ts","sourceRoot":"","sources":["../../src/stories/sample-data.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGT,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"sample-data.d.ts","sourceRoot":"","sources":["../../src/stories/sample-data.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGT,MAAM,iCAAiC,CAAC;AA6EzC,wBAAgB,oBAAoB,IAAI,QAAQ,CAmB/C;AAaD,wBAAgB,yBAAyB,IAAI,QAAQ,CAmBpD"}
|