@principal-ai/file-city-react 0.5.0 → 0.5.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"drawLayeredBuildings.d.ts","sourceRoot":"","sources":["../../../src/render/client/drawLayeredBuildings.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,mBAAmB,EACnB,cAAc,EACf,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAI1E,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,CAAC;AAE/D;;;GAGG;AACH,qBAAa,UAAU;IAErB,OAAO,CAAC,UAAU,CAA6E;IAE/F,OAAO,CAAC,cAAc,CAAuE;IAE7F,OAAO,CAAC,WAAW,CAA6E;gBAEpF,MAAM,EAAE,cAAc,EAAE;IAIpC,OAAO,CAAC,UAAU;IA0BlB;;;;OAIG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAO,GAAG,UAAuB,GAC3C,KAAK,CAAC;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;CAuCrD;AA8BD,wBAAgB,QAAQ,CACtB,GAAG,EAAE,wBAAwB,EAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,QAqBjB;AA0VD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,wBAAwB,EAC7B,SAAS,EAAE,YAAY,EAAE,EACzB,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACjE,KAAK,EAAE,MAAM,EAAE,wDAAwD;AACvE,MAAM,EAAE,cAAc,EAAE,EACxB,eAAe,CAAC,EAAE,YAAY,GAAG,IAAI,EACrC,QAAQ,CAAC,EAAE,OAAO,EAClB,qBAAqB,CAAC,EAAE,MAAM,EAC9B,YAAY,CAAC,EAAE;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,EACD,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,yDAAyD;AACxF,mBAAmB,GAAE,OAAc,EACnC,YAAY,GAAE,MAAU,EAAE,uDAAuD;AACjF,UAAU,CAAC,EAAE,UAAU,QAgQxB;AAGD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,wBAAwB,EAC7B,SAAS,EAAE,YAAY,EAAE,EACzB,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACjE,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,EAAE,EACxB,eAAe,CAAC,EAAE,YAAY,GAAG,IAAI,EACrC,oBAAoB,CAAC,EAAE,MAAM,EAC7B,aAAa,CAAC,EAAE,OAAO,EACvB,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,EAC/B,iBAAiB,CAAC,EAAE,OAAO,EAC3B,YAAY,GAAE,MAAU,EAAE,2DAA2D;AACrF,UAAU,CAAC,EAAE,UAAU,EAAE,2CAA2C;AACpE,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,QA8J1C"}
1
+ {"version":3,"file":"drawLayeredBuildings.d.ts","sourceRoot":"","sources":["../../../src/render/client/drawLayeredBuildings.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,mBAAmB,EACnB,cAAc,EACf,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAI1E,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,CAAC;AAE/D;;;GAGG;AACH,qBAAa,UAAU;IAErB,OAAO,CAAC,UAAU,CAA6E;IAE/F,OAAO,CAAC,cAAc,CAAuE;IAE7F,OAAO,CAAC,WAAW,CAA6E;gBAEpF,MAAM,EAAE,cAAc,EAAE;IAIpC,OAAO,CAAC,UAAU;IA0BlB;;;;OAIG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAO,GAAG,UAAuB,GAC3C,KAAK,CAAC;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;CAuCrD;AA8BD,wBAAgB,QAAQ,CACtB,GAAG,EAAE,wBAAwB,EAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,QAqBjB;AA0VD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,wBAAwB,EAC7B,SAAS,EAAE,YAAY,EAAE,EACzB,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACjE,KAAK,EAAE,MAAM,EAAE,wDAAwD;AACvE,MAAM,EAAE,cAAc,EAAE,EACxB,eAAe,CAAC,EAAE,YAAY,GAAG,IAAI,EACrC,QAAQ,CAAC,EAAE,OAAO,EAClB,qBAAqB,CAAC,EAAE,MAAM,EAC9B,YAAY,CAAC,EAAE;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,EACD,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,yDAAyD;AACxF,mBAAmB,GAAE,OAAc,EACnC,YAAY,GAAE,MAAU,EAAE,uDAAuD;AACjF,UAAU,CAAC,EAAE,UAAU,QAgQxB;AAGD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,wBAAwB,EAC7B,SAAS,EAAE,YAAY,EAAE,EACzB,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACjE,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,EAAE,EACxB,eAAe,CAAC,EAAE,YAAY,GAAG,IAAI,EACrC,oBAAoB,CAAC,EAAE,MAAM,EAC7B,aAAa,CAAC,EAAE,OAAO,EACvB,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,EAC/B,iBAAiB,CAAC,EAAE,OAAO,EAC3B,YAAY,GAAE,MAAU,EAAE,2DAA2D;AACrF,UAAU,CAAC,EAAE,UAAU,EAAE,2CAA2C;AACpE,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,QA0K1C"}
@@ -655,12 +655,16 @@ iconMap) {
655
655
  // Draw file type icon if enabled and icon map is provided
656
656
  // Track icon size for positioning file name below
657
657
  let iconBottomY = pos.y;
658
+ let hasIcon = false;
658
659
  if (showFileTypeIcons && iconMap) {
659
660
  const iconConfig = (0, fileTypeIcons_1.getFileTypeIcon)(building.path, iconMap);
660
661
  if (iconConfig) {
662
+ hasIcon = true;
661
663
  // For wide buildings (wider than tall), shift icon up to make room for text below
664
+ // Only shift if text will actually be rendered
665
+ const willShowText = showFileNames && width > 100 && height > 30;
662
666
  const isWide = width > height;
663
- const iconYOffset = isWide ? -height * 0.15 : 0;
667
+ const iconYOffset = (willShowText && isWide) ? -height * 0.15 : 0;
664
668
  const iconY = pos.y + iconYOffset;
665
669
  (0, fileTypeIcons_1.drawFileTypeIcon)(ctx, iconConfig, pos.x, iconY, width, height);
666
670
  // Calculate where the icon ends vertically
@@ -691,13 +695,21 @@ iconMap) {
691
695
  const fontSize = Math.min(30, Math.max(10, Math.floor(Math.min(width, height) * 0.3)));
692
696
  ctx.font = `${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
693
697
  ctx.textAlign = 'center';
694
- ctx.textBaseline = 'top'; // Changed from 'middle' to 'top'
695
698
  const textMetrics = ctx.measureText(fileName);
696
699
  const textWidth = textMetrics.width;
697
700
  if (textWidth < width - 8) {
698
- // Add spacing between icon and text
699
- const spacing = 4;
700
- const textY = iconBottomY + spacing;
701
+ let textY;
702
+ if (hasIcon) {
703
+ // Position text below icon
704
+ ctx.textBaseline = 'top';
705
+ const spacing = 4;
706
+ textY = iconBottomY + spacing;
707
+ }
708
+ else {
709
+ // Center text vertically when no icon
710
+ ctx.textBaseline = 'middle';
711
+ textY = pos.y;
712
+ }
701
713
  // Text
702
714
  ctx.fillStyle = 'rgba(255, 255, 255, 0.95)';
703
715
  ctx.fillText(fileName, pos.x, textY);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ai/file-city-react",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "React components for File City visualization",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -894,12 +894,16 @@ export function drawLayeredBuildings(
894
894
  // Draw file type icon if enabled and icon map is provided
895
895
  // Track icon size for positioning file name below
896
896
  let iconBottomY = pos.y;
897
+ let hasIcon = false;
897
898
  if (showFileTypeIcons && iconMap) {
898
899
  const iconConfig = getFileTypeIcon(building.path, iconMap);
899
900
  if (iconConfig) {
901
+ hasIcon = true;
900
902
  // For wide buildings (wider than tall), shift icon up to make room for text below
903
+ // Only shift if text will actually be rendered
904
+ const willShowText = showFileNames && width > 100 && height > 30;
901
905
  const isWide = width > height;
902
- const iconYOffset = isWide ? -height * 0.15 : 0;
906
+ const iconYOffset = (willShowText && isWide) ? -height * 0.15 : 0;
903
907
  const iconY = pos.y + iconYOffset;
904
908
 
905
909
  drawFileTypeIcon(ctx, iconConfig, pos.x, iconY, width, height);
@@ -933,15 +937,23 @@ export function drawLayeredBuildings(
933
937
  const fontSize = Math.min(30, Math.max(10, Math.floor(Math.min(width, height) * 0.3)));
934
938
  ctx.font = `${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`;
935
939
  ctx.textAlign = 'center';
936
- ctx.textBaseline = 'top'; // Changed from 'middle' to 'top'
937
940
 
938
941
  const textMetrics = ctx.measureText(fileName);
939
942
  const textWidth = textMetrics.width;
940
943
 
941
944
  if (textWidth < width - 8) {
942
- // Add spacing between icon and text
943
- const spacing = 4;
944
- const textY = iconBottomY + spacing;
945
+ let textY: number;
946
+
947
+ if (hasIcon) {
948
+ // Position text below icon
949
+ ctx.textBaseline = 'top';
950
+ const spacing = 4;
951
+ textY = iconBottomY + spacing;
952
+ } else {
953
+ // Center text vertically when no icon
954
+ ctx.textBaseline = 'middle';
955
+ textY = pos.y;
956
+ }
945
957
 
946
958
  // Text
947
959
  ctx.fillStyle = 'rgba(255, 255, 255, 0.95)';
@@ -11,7 +11,7 @@ const meta = {
11
11
  layout: 'fullscreen',
12
12
  },
13
13
  decorators: [
14
- Story => (
14
+ (Story: React.ComponentType) => (
15
15
  <div style={{ width: '100vw', height: '100vh', backgroundColor: '#1a1a1a' }}>
16
16
  <Story />
17
17
  </div>
@@ -199,7 +199,7 @@ function createAllFileTypesCityData() {
199
199
  };
200
200
  });
201
201
 
202
- const fileTree = buildFileSystemTreeFromFileInfoList(fileInfos);
202
+ const fileTree = buildFileSystemTreeFromFileInfoList(fileInfos, 'all-file-types');
203
203
  const builder = new CodeCityBuilderWithGrid();
204
204
  return builder.buildCityFromFileSystem(fileTree, '', {
205
205
  paddingTop: 2,
@@ -230,6 +230,8 @@ export const AllFileTypesWithColors: Story = {
230
230
  enableZoom={true}
231
231
  buildingBorderRadius={2}
232
232
  districtBorderRadius={4}
233
+ showFileTypeIcons={true}
234
+ showFileNames={true}
233
235
  />
234
236
  <div
235
237
  style={{
@@ -288,7 +290,7 @@ export const TestFilesWithIcons: Story = {
288
290
  };
289
291
  });
290
292
 
291
- const fileTree = buildFileSystemTreeFromFileInfoList(fileInfos);
293
+ const fileTree = buildFileSystemTreeFromFileInfoList(fileInfos, 'test-files');
292
294
  const builder = new CodeCityBuilderWithGrid();
293
295
  const cityData = builder.buildCityFromFileSystem(fileTree, '', {
294
296
  paddingTop: 2,
@@ -50,7 +50,7 @@ const meta = {
50
50
  layout: 'fullscreen',
51
51
  },
52
52
  decorators: [
53
- Story => (
53
+ (Story: React.ComponentType) => (
54
54
  <div style={{ width: '100vw', height: '100vh' }}>
55
55
  <Story />
56
56
  </div>
@@ -12,7 +12,7 @@ const meta = {
12
12
  layout: 'fullscreen',
13
13
  },
14
14
  decorators: [
15
- Story => (
15
+ (Story: React.ComponentType) => (
16
16
  <div style={{ width: '100vw', height: '100vh', backgroundColor: '#1a1a1a' }}>
17
17
  <Story />
18
18
  </div>
@@ -200,7 +200,6 @@ export const WithAbstractionLayer: Story = {
200
200
  color: '#1e40af',
201
201
  priority: 0,
202
202
  items: [],
203
- // @ts-expect-error - abstraction layer specific properties
204
203
  abstractionLayer: true,
205
204
  abstractionConfig: {
206
205
  maxZoomLevel: 2.0,
@@ -208,7 +207,7 @@ export const WithAbstractionLayer: Story = {
208
207
  backgroundColor: '#1e40af',
209
208
  allowRootAbstraction: false,
210
209
  },
211
- },
210
+ } as HighlightLayer,
212
211
  ],
213
212
  fullSize: true,
214
213
  enableZoom: true,
@@ -11,7 +11,7 @@ const meta = {
11
11
  layout: 'fullscreen',
12
12
  },
13
13
  decorators: [
14
- Story => (
14
+ (Story: React.ComponentType) => (
15
15
  <div style={{ height: '100vh', width: '100vw' }}>
16
16
  <Story />
17
17
  </div>
@@ -353,7 +353,7 @@ const meta = {
353
353
  layout: 'fullscreen',
354
354
  },
355
355
  decorators: [
356
- Story => (
356
+ (Story: React.ComponentType) => (
357
357
  <div style={{ width: '100vw', height: '100vh' }}>
358
358
  <Story />
359
359
  </div>