@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.
@@ -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":"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"}
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 = [], onLayerToggle, focusDirectory = null, rootDirectoryName, onDirectorySelect, onFileClick, enableZoom = false, zoomToPath = null, 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
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":"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"}
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;AAIxD,OAAO,QAAQ,OAAO,CAAC;IAErB,UAAU,GAAG,CAAC;QAEZ,UAAU,iBAAkB,SAAQ,aAAa;SAAG;KACrD;CACF;AAGD,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;AAGrD,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;CAC5B;AAED,gDAAgD;AAChD,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,aAAa,GACb,UAAU,GACV,MAAM,CAAC;AAGX,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wCAAwC;AACxC,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,QAAQ,CAAC;AAErD,oFAAoF;AACpF,MAAM,WAAW,WAAW;IAC1B,qDAAqD;IACrD,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,yDAAyD;AACzD,eAAO,MAAM,qBAAqB,EAAE,WAAW,EAS9C,CAAC;AA67BF,MAAM,WAAW,aAAa;IAC5B,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmBD,wBAAgB,WAAW,SAE1B;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,QAE/D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,QAEvF;AAED;;GAEG;AACH,wBAAgB,eAAe;OA9BA,MAAM;OAAK,MAAM;OAAK,MAAM;SAgC1D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,gBAAgB,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,EAC9D,OAAO,CAAC,EAAE,aAAa,QAGxB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,QAEtE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,EAChD,OAAO,CAAC,EAAE,aAAa,QAGxB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,QAEpE;AAED,wBAAgB,iBAAiB;OAhFA,MAAM;OAAK,MAAM;OAAK,MAAM;SAkF5D;AAED;;;GAGG;AACH,wBAAgB,cAAc,kBAE7B;AAED;;;GAGG;AACH,wBAAgB,aAAa,kBAE5B;AA48BD,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,QAAQ,EAAE,QAAQ,CAAC;IACnB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IACnD,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,8BAA8B;IAC9B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,2BAA2B;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kEAAkE;IAClE,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,yEAAyE;IACzE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uCAAuC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2IAA2I;IAC3I,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACvC,4EAA4E;IAC5E,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC,kEAAkE;IAClE,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,KAAc,EACd,MAAY,EACZ,eAAe,EACf,SAAS,EACT,KAAK,EACL,SAAS,EACT,OAAO,EAAE,eAAe,EACxB,YAAY,EACZ,YAAmB,EACnB,eAAe,EAAE,uBAAuB,EACxC,aAAa,EAAE,qBAAqB,EACpC,UAAU,EAAE,WAAkB,EAC9B,SAAiB,EACjB,cAAuC,EACvC,YAA4C,EAC5C,aAAwB,EACxB,WAAe,EACf,YAAoC,EACpC,cAAc,EAAE,sBAAsB,EACtC,UAAU,EAAE,kBAAkB,EAC9B,iBAAiB,EAAE,kBAAkB,EACrC,eAA2B,EAC3B,SAAqB,EACrB,gBAAuB,EACvB,sBAA8B,EAC9B,eAAe,GAChB,EAAE,eAAe,2CAiKjB;AAED,eAAe,UAAU,CAAC"}
@@ -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 = 0.05) {
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
- const color = getColorForFile(building);
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("meshStandardMaterial", { metalness: 0.1, roughness: 0.35 })] }), _jsx(BuildingEdges, { buildings: buildingData.map(d => ({
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 floats above building
470
- const flatY = minHeight + baseOffset + 0.5;
471
- const grownY = buildingTop + iconSize / 2 + 2;
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
- // Rotate from flat (facing up) to upright (facing camera-ish)
475
- // Flat: -Math.PI / 2 (facing up)
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 baseSize = Math.max(width * 1.2, 8);
541
- const heightBoost = Math.min(targetHeight / 20, 3);
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 = 0; // Center of district when flat
569
- const grownZ = depth / 2 + 2; // Edge of district when grown
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 })] })), district.label && (_jsx(Text, { position: [0, textY, textZ], rotation: [textRotationX, 0, 0], fontSize: Math.min(3, width / 6), color: labelColor, anchorX: "center", anchorY: "middle", outlineWidth: 0.1, outlineColor: "#0f172a", children: dirName }))] }));
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
- return citySize / (2 * tanHalfFov * effectiveAspect);
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
- // Priority 2: highlight layers (only if no focusDirectory is pending)
1261
- // Don't focus on highlights if we're waiting for cameraFocusDirectory to catch up
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 = [], isolationMode = 'transparent', dimOpacity: _dimOpacity = 0.15, isLoading = false, loadingMessage = 'Loading file city...', emptyMessage = 'No file tree data available', heightScaling = 'logarithmic', linearScale = 0.05, focusDirectory = null, focusColor = null, onDirectorySelect: _onDirectorySelect, backgroundColor = '#0f172a', textColor = '#94a3b8', selectedBuilding = null, adaptCameraToBuildings = false, }) {
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, style: {
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,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC"}
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
@@ -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;AAClE,YAAY,EACV,eAAe,EACf,eAAe,EACf,cAAc,IAAI,wBAAwB,EAC1C,aAAa,IAAI,uBAAuB,EACxC,aAAa,EACb,aAAa,EACb,aAAa,GACd,MAAM,yBAAyB,CAAC;AAIjC,YAAY,EAAE,cAAc,IAAI,YAAY,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;AA2EzC,wBAAgB,oBAAoB,IAAI,QAAQ,CAmB/C;AAaD,wBAAgB,yBAAyB,IAAI,QAAQ,CAmBpD"}
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"}