@principal-ai/file-city-react 0.3.0

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.
Files changed (51) hide show
  1. package/dist/builder/cityDataUtils.d.ts +15 -0
  2. package/dist/builder/cityDataUtils.d.ts.map +1 -0
  3. package/dist/builder/cityDataUtils.js +348 -0
  4. package/dist/components/ArchitectureMapHighlightLayers.d.ts +63 -0
  5. package/dist/components/ArchitectureMapHighlightLayers.d.ts.map +1 -0
  6. package/dist/components/ArchitectureMapHighlightLayers.js +1040 -0
  7. package/dist/components/CityViewWithReactFlow.d.ts +14 -0
  8. package/dist/components/CityViewWithReactFlow.d.ts.map +1 -0
  9. package/dist/components/CityViewWithReactFlow.js +266 -0
  10. package/dist/config/files.json +996 -0
  11. package/dist/hooks/useCodeCityData.d.ts +21 -0
  12. package/dist/hooks/useCodeCityData.d.ts.map +1 -0
  13. package/dist/hooks/useCodeCityData.js +57 -0
  14. package/dist/index.d.ts +14 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +29 -0
  17. package/dist/render/client/drawLayeredBuildings.d.ts +51 -0
  18. package/dist/render/client/drawLayeredBuildings.d.ts.map +1 -0
  19. package/dist/render/client/drawLayeredBuildings.js +650 -0
  20. package/dist/stories/ArchitectureMapGridLayout.stories.d.ts +73 -0
  21. package/dist/stories/ArchitectureMapGridLayout.stories.d.ts.map +1 -0
  22. package/dist/stories/ArchitectureMapGridLayout.stories.js +345 -0
  23. package/dist/stories/ArchitectureMapHighlightLayers.stories.d.ts +78 -0
  24. package/dist/stories/ArchitectureMapHighlightLayers.stories.d.ts.map +1 -0
  25. package/dist/stories/ArchitectureMapHighlightLayers.stories.js +270 -0
  26. package/dist/stories/CityViewWithReactFlow.stories.d.ts +24 -0
  27. package/dist/stories/CityViewWithReactFlow.stories.d.ts.map +1 -0
  28. package/dist/stories/CityViewWithReactFlow.stories.js +778 -0
  29. package/dist/stories/sample-data.d.ts +4 -0
  30. package/dist/stories/sample-data.d.ts.map +1 -0
  31. package/dist/stories/sample-data.js +268 -0
  32. package/dist/types/react-types.d.ts +17 -0
  33. package/dist/types/react-types.d.ts.map +1 -0
  34. package/dist/types/react-types.js +4 -0
  35. package/dist/utils/fileColorHighlightLayers.d.ts +86 -0
  36. package/dist/utils/fileColorHighlightLayers.d.ts.map +1 -0
  37. package/dist/utils/fileColorHighlightLayers.js +283 -0
  38. package/package.json +49 -0
  39. package/src/builder/cityDataUtils.ts +430 -0
  40. package/src/components/ArchitectureMapHighlightLayers.tsx +1518 -0
  41. package/src/components/CityViewWithReactFlow.tsx +365 -0
  42. package/src/config/files.json +996 -0
  43. package/src/hooks/useCodeCityData.ts +82 -0
  44. package/src/index.ts +64 -0
  45. package/src/render/client/drawLayeredBuildings.ts +946 -0
  46. package/src/stories/ArchitectureMapGridLayout.stories.tsx +410 -0
  47. package/src/stories/ArchitectureMapHighlightLayers.stories.tsx +312 -0
  48. package/src/stories/CityViewWithReactFlow.stories.tsx +787 -0
  49. package/src/stories/sample-data.ts +301 -0
  50. package/src/types/react-types.ts +18 -0
  51. package/src/utils/fileColorHighlightLayers.ts +378 -0
@@ -0,0 +1,410 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import {
3
+ CodeCityBuilderWithGrid,
4
+ buildFileSystemTreeFromFileInfoList,
5
+ CityData,
6
+ } from '@principal-ai/file-city-builder';
7
+
8
+ import { ArchitectureMapHighlightLayers } from '../components/ArchitectureMapHighlightLayers';
9
+
10
+ // Type definitions needed for the story
11
+ interface FileInfo {
12
+ name: string;
13
+ path: string;
14
+ relativePath: string;
15
+ size: number;
16
+ extension: string;
17
+ lastModified: Date;
18
+ isDirectory: boolean;
19
+ }
20
+
21
+ interface CodebaseView {
22
+ id: string;
23
+ version: string;
24
+ name: string;
25
+ description: string;
26
+ overviewPath: string;
27
+ cells: {
28
+ [key: string]: {
29
+ files: string[];
30
+ coordinates: [number, number];
31
+ };
32
+ };
33
+ metadata?: {
34
+ ui?: {
35
+ paddingTop?: number;
36
+ paddingBottom?: number;
37
+ paddingLeft?: number;
38
+ paddingRight?: number;
39
+ paddingInner?: number;
40
+ paddingOuter?: number;
41
+ };
42
+ };
43
+ }
44
+
45
+ const meta = {
46
+ title: 'Components/ArchitectureMapHighlightLayers/Grid Layout',
47
+ component: ArchitectureMapHighlightLayers,
48
+ parameters: {
49
+ layout: 'fullscreen',
50
+ },
51
+ decorators: [
52
+ Story => (
53
+ <div style={{ width: '100vw', height: '100vh' }}>
54
+ <Story />
55
+ </div>
56
+ ),
57
+ ],
58
+ } satisfies Meta<typeof ArchitectureMapHighlightLayers>;
59
+
60
+ export default meta;
61
+ type Story = StoryObj<typeof meta>;
62
+
63
+ // Helper function to create city data with grid layout
64
+ function createGridLayoutCityData(config: CodebaseView, customFilePaths?: string[]): CityData {
65
+ // Create a mock file tree with typical monorepo structure
66
+ const filePaths = customFilePaths || [
67
+ // Core source files
68
+ 'src/index.ts',
69
+ 'src/components/App.tsx',
70
+ 'src/components/Header.tsx',
71
+ 'src/utils/helpers.ts',
72
+ 'lib/core.ts',
73
+ 'lib/utils.ts',
74
+
75
+ // Configuration
76
+ '.a24z/config.json',
77
+ '.principleMD/settings.json',
78
+ 'config/webpack.config.js',
79
+
80
+ // Documentation
81
+ 'docs/README.md',
82
+ 'docs/API.md',
83
+ 'examples/basic.ts',
84
+ 'examples/advanced.ts',
85
+
86
+ // Testing
87
+ 'tests/unit/app.test.ts',
88
+ 'tests/integration/api.test.ts',
89
+ '__tests__/components.test.tsx',
90
+ 'test-utils/helpers.ts',
91
+
92
+ // Build outputs
93
+ 'dist/bundle.js',
94
+ 'build/index.html',
95
+ '.next/static/chunks/pages.js',
96
+
97
+ // Dependencies
98
+ 'node_modules/react/index.js',
99
+ 'node_modules/typescript/lib/typescript.js',
100
+ 'packages/shared/index.ts',
101
+ 'packages/ui/components.tsx',
102
+
103
+ // Assets
104
+ 'public/index.html',
105
+ 'public/favicon.ico',
106
+ 'static/logo.svg',
107
+ 'assets/styles.css',
108
+
109
+ // Root files
110
+ 'package.json',
111
+ 'README.md',
112
+ '.gitignore',
113
+ 'tsconfig.json',
114
+ ];
115
+
116
+ // Convert file paths to FileInfo objects
117
+ const fileInfos: FileInfo[] = filePaths.map(path => ({
118
+ name: path.split('/').pop() || path,
119
+ path: path,
120
+ relativePath: path,
121
+ size: Math.random() * 10000, // Random size for demo
122
+ extension: path.includes('.') ? '.' + (path.split('.').pop() || '') : '',
123
+ lastModified: new Date(),
124
+ isDirectory: false,
125
+ }));
126
+
127
+ // Build a proper file tree with hierarchy
128
+ const fileTree = buildFileSystemTreeFromFileInfoList(fileInfos as any, 'demo-sha');
129
+ const cityBuilder = new CodeCityBuilderWithGrid();
130
+
131
+ // Use the new integrated grid layout builder with adaptive sizing
132
+ // This allows the grid to calculate its own optimal dimensions
133
+ return cityBuilder.buildCityFromFileSystem(fileTree, '', {
134
+ gridLayout: config as any,
135
+ });
136
+ }
137
+
138
+ // Minimal config - tests default UI metadata
139
+ export const DefaultsTest: Story = {
140
+ args: {
141
+ cityData: createGridLayoutCityData({
142
+ id: 'defaults-test',
143
+ version: '1.0.0',
144
+ name: 'Test Default UI Settings',
145
+ description: 'Tests default UI metadata settings when none are provided',
146
+ overviewPath: 'README.md',
147
+ cells: {
148
+ Source: {
149
+ files: ['src', 'lib'],
150
+ coordinates: [0, 0],
151
+ },
152
+ Config: {
153
+ files: ['config', '.*'],
154
+ coordinates: [0, 1],
155
+ },
156
+ Tests: {
157
+ files: ['test*', '__tests__'],
158
+ coordinates: [1, 0],
159
+ },
160
+ Build: {
161
+ files: ['dist', 'build', 'node_modules'],
162
+ coordinates: [1, 1],
163
+ },
164
+ },
165
+ // No metadata.ui provided - should use defaults
166
+ }),
167
+ showGrid: true,
168
+ showFileNames: false,
169
+ showDirectoryLabels: true,
170
+ fullSize: true,
171
+ enableZoom: true,
172
+ },
173
+ };
174
+
175
+ // 2x2 Grid Layout with Labels
176
+ export const TwoByTwoGrid: Story = {
177
+ args: {
178
+ cityData: createGridLayoutCityData({
179
+ id: 'two-by-two-grid',
180
+ version: '1.0.0',
181
+ name: 'Two by Two Grid Layout',
182
+ description: 'A 2x2 grid layout organizing code into four quadrants',
183
+ overviewPath: 'README.md',
184
+ cells: {
185
+ Source: {
186
+ files: ['src', 'lib'],
187
+ coordinates: [0, 0],
188
+ },
189
+ Configuration: {
190
+ files: ['config', '.a24z', '.principleMD', 'tsconfig.json', 'package.json'],
191
+ coordinates: [1, 0],
192
+ },
193
+ Testing: {
194
+ files: ['tests', '__tests__', 'test-utils'],
195
+ coordinates: [0, 1],
196
+ },
197
+ Documentation: {
198
+ files: ['docs', 'examples', 'README.md'],
199
+ coordinates: [1, 1],
200
+ },
201
+ },
202
+ metadata: {
203
+ ui: {
204
+ paddingTop: 10,
205
+ paddingBottom: 10,
206
+ paddingLeft: 15,
207
+ paddingRight: 15,
208
+ paddingInner: 8,
209
+ paddingOuter: 20,
210
+ },
211
+ },
212
+ }),
213
+ showGrid: true,
214
+ showFileNames: false,
215
+ showDirectoryLabels: true,
216
+ fullSize: true,
217
+ enableZoom: true,
218
+ },
219
+ };
220
+
221
+ // 3x3 Grid Layout
222
+ export const ThreeByThreeGrid: Story = {
223
+ args: {
224
+ cityData: createGridLayoutCityData({
225
+ id: 'three-by-three-grid',
226
+ version: '1.0.0',
227
+ name: 'Three by Three Grid Layout',
228
+ description: 'A 3x3 grid layout for more granular organization',
229
+ overviewPath: 'README.md',
230
+ cells: {
231
+ Source: {
232
+ files: ['src'],
233
+ coordinates: [0, 0],
234
+ },
235
+ Libraries: {
236
+ files: ['lib'],
237
+ coordinates: [1, 0],
238
+ },
239
+ Packages: {
240
+ files: ['packages'],
241
+ coordinates: [2, 0],
242
+ },
243
+ Tests: {
244
+ files: ['tests', '__tests__'],
245
+ coordinates: [0, 1],
246
+ },
247
+ Configuration: {
248
+ files: ['config', '.*', 'tsconfig.json', 'package.json'],
249
+ coordinates: [1, 1],
250
+ },
251
+ Documentation: {
252
+ files: ['docs', 'README.md'],
253
+ coordinates: [2, 1],
254
+ },
255
+ 'Test Utils': {
256
+ files: ['test-utils'],
257
+ coordinates: [0, 2],
258
+ },
259
+ Build: {
260
+ files: ['dist', 'build', '.next'],
261
+ coordinates: [1, 2],
262
+ },
263
+ Assets: {
264
+ files: ['public', 'static', 'assets'],
265
+ coordinates: [2, 2],
266
+ },
267
+ },
268
+ }),
269
+ showGrid: true,
270
+ fullSize: true,
271
+ enableZoom: true,
272
+ },
273
+ };
274
+
275
+ // Sparse Grid Layout (gaps in grid)
276
+ export const SparseGrid: Story = {
277
+ args: {
278
+ cityData: createGridLayoutCityData({
279
+ id: 'sparse-grid',
280
+ version: '1.0.0',
281
+ name: 'Sparse Grid Layout',
282
+ description: 'A grid with intentional gaps for visual organization',
283
+ overviewPath: 'README.md',
284
+ cells: {
285
+ Source: {
286
+ files: ['src', 'lib'],
287
+ coordinates: [0, 0],
288
+ },
289
+ Tests: {
290
+ files: ['tests', '__tests__', 'test-utils'],
291
+ coordinates: [2, 0],
292
+ },
293
+ Documentation: {
294
+ files: ['docs', 'examples', 'README.md'],
295
+ coordinates: [0, 2],
296
+ },
297
+ Build: {
298
+ files: ['dist', 'build', '.next', 'node_modules'],
299
+ coordinates: [2, 2],
300
+ },
301
+ },
302
+ }),
303
+ showGrid: true,
304
+ fullSize: true,
305
+ enableZoom: true,
306
+ },
307
+ };
308
+
309
+ // Custom colored grid with highlight layers
310
+ export const GridWithHighlights: Story = {
311
+ args: {
312
+ cityData: createGridLayoutCityData({
313
+ id: 'grid-with-highlights',
314
+ version: '1.0.0',
315
+ name: 'Grid with Highlights',
316
+ description: 'Grid layout with custom highlight layers',
317
+ overviewPath: 'README.md',
318
+ cells: {
319
+ Source: {
320
+ files: ['src', 'lib'],
321
+ coordinates: [0, 0],
322
+ },
323
+ Tests: {
324
+ files: ['tests', '__tests__'],
325
+ coordinates: [1, 0],
326
+ },
327
+ Config: {
328
+ files: ['config', '.*'],
329
+ coordinates: [0, 1],
330
+ },
331
+ Build: {
332
+ files: ['dist', 'build'],
333
+ coordinates: [1, 1],
334
+ },
335
+ },
336
+ }),
337
+ highlightLayers: [
338
+ {
339
+ id: 'modified-files',
340
+ name: 'Modified Files',
341
+ enabled: true,
342
+ color: '#3b82f6',
343
+ priority: 1,
344
+ items: [
345
+ { path: 'src/components/App.tsx', type: 'file' },
346
+ { path: 'src/utils/helpers.ts', type: 'file' },
347
+ ],
348
+ },
349
+ {
350
+ id: 'test-coverage',
351
+ name: 'Test Coverage',
352
+ enabled: true,
353
+ color: '#10b981',
354
+ priority: 2,
355
+ items: [{ path: 'tests', type: 'directory' }],
356
+ },
357
+ ],
358
+ showLayerControls: true,
359
+ showGrid: true,
360
+ fullSize: true,
361
+ enableZoom: true,
362
+ },
363
+ };
364
+
365
+ // Large grid (5x5)
366
+ export const LargeGrid: Story = {
367
+ args: {
368
+ cityData: createGridLayoutCityData({
369
+ id: 'large-grid',
370
+ version: '1.0.0',
371
+ name: 'Large 5x5 Grid',
372
+ description: 'A large grid for complex projects',
373
+ overviewPath: 'README.md',
374
+ cells: {
375
+ 'Core Source': { files: ['src/core'], coordinates: [0, 0] },
376
+ Components: { files: ['src/components'], coordinates: [1, 0] },
377
+ Utils: { files: ['src/utils'], coordinates: [2, 0] },
378
+ Hooks: { files: ['src/hooks'], coordinates: [3, 0] },
379
+ Types: { files: ['src/types'], coordinates: [4, 0] },
380
+
381
+ 'Unit Tests': { files: ['tests/unit'], coordinates: [0, 1] },
382
+ Integration: { files: ['tests/integration'], coordinates: [1, 1] },
383
+ E2E: { files: ['tests/e2e'], coordinates: [2, 1] },
384
+ 'Test Utils': { files: ['test-utils'], coordinates: [3, 1] },
385
+ Fixtures: { files: ['fixtures'], coordinates: [4, 1] },
386
+
387
+ Config: { files: ['config'], coordinates: [0, 2] },
388
+ Scripts: { files: ['scripts'], coordinates: [1, 2] },
389
+ Tools: { files: ['tools'], coordinates: [2, 2] },
390
+ 'CI/CD': { files: ['.github', '.gitlab'], coordinates: [3, 2] },
391
+ Docker: { files: ['docker', 'Dockerfile'], coordinates: [4, 2] },
392
+
393
+ Docs: { files: ['docs'], coordinates: [0, 3] },
394
+ Examples: { files: ['examples'], coordinates: [1, 3] },
395
+ API: { files: ['api'], coordinates: [2, 3] },
396
+ Packages: { files: ['packages'], coordinates: [3, 3] },
397
+ Libs: { files: ['lib'], coordinates: [4, 3] },
398
+
399
+ Build: { files: ['dist'], coordinates: [0, 4] },
400
+ Public: { files: ['public'], coordinates: [1, 4] },
401
+ Assets: { files: ['assets'], coordinates: [2, 4] },
402
+ Static: { files: ['static'], coordinates: [3, 4] },
403
+ 'Node Modules': { files: ['node_modules'], coordinates: [4, 4] },
404
+ },
405
+ }),
406
+ showGrid: true,
407
+ fullSize: true,
408
+ enableZoom: true,
409
+ },
410
+ };
@@ -0,0 +1,312 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { useState } from 'react';
3
+
4
+ import { ArchitectureMapHighlightLayers } from '../components/ArchitectureMapHighlightLayers';
5
+ import { HighlightLayer } from '../render/client/drawLayeredBuildings';
6
+ import { createSampleCityData } from './sample-data';
7
+
8
+ const meta = {
9
+ title: 'Components/ArchitectureMapHighlightLayers',
10
+ component: ArchitectureMapHighlightLayers,
11
+ parameters: {
12
+ layout: 'fullscreen',
13
+ },
14
+ decorators: [
15
+ Story => (
16
+ <div style={{ width: '100vw', height: '100vh', backgroundColor: '#1a1a1a' }}>
17
+ <Story />
18
+ </div>
19
+ ),
20
+ ],
21
+ } satisfies Meta<typeof ArchitectureMapHighlightLayers>;
22
+
23
+ export default meta;
24
+ type Story = StoryObj<typeof meta>;
25
+
26
+ // Basic story with sample city data
27
+ export const Default: Story = {
28
+ args: {
29
+ cityData: createSampleCityData(),
30
+ showGrid: false,
31
+ fullSize: true,
32
+ canvasBackgroundColor: '#0f1419',
33
+ defaultBuildingColor: '#36454F',
34
+ defaultDirectoryColor: '#111827',
35
+ enableZoom: true,
36
+ },
37
+ };
38
+
39
+ // Story with highlight layers
40
+ export const WithHighlightLayers: Story = {
41
+ render: function RenderWithHighlightLayers() {
42
+ const [layers, setLayers] = useState<HighlightLayer[]>([
43
+ {
44
+ id: 'modified-files',
45
+ name: 'Modified Files',
46
+ enabled: true,
47
+ color: '#3b82f6',
48
+ priority: 1,
49
+ items: [
50
+ { path: 'src/components/App.tsx', type: 'file' },
51
+ { path: 'src/components/Header.tsx', type: 'file' },
52
+ { path: 'src/utils/helpers.ts', type: 'file' },
53
+ ],
54
+ },
55
+ {
56
+ id: 'new-files',
57
+ name: 'New Files',
58
+ enabled: true,
59
+ color: '#10b981',
60
+ priority: 2,
61
+ items: [
62
+ { path: 'src/components/Footer.tsx', type: 'file' },
63
+ { path: 'tests/unit/footer.test.tsx', type: 'file' },
64
+ ],
65
+ },
66
+ {
67
+ id: 'deleted-files',
68
+ name: 'Deleted Files',
69
+ enabled: false,
70
+ color: '#ef4444',
71
+ priority: 3,
72
+ items: [{ path: 'src/deprecated/OldComponent.tsx', type: 'file' }],
73
+ },
74
+ ]);
75
+
76
+ const handleLayerToggle = (layerId: string, enabled: boolean) => {
77
+ setLayers(prev => prev.map(layer => (layer.id === layerId ? { ...layer, enabled } : layer)));
78
+ };
79
+
80
+ return (
81
+ <ArchitectureMapHighlightLayers
82
+ cityData={createSampleCityData()}
83
+ highlightLayers={layers}
84
+ onLayerToggle={handleLayerToggle}
85
+ showLayerControls={true}
86
+ fullSize={true}
87
+ canvasBackgroundColor="#0f1419"
88
+ defaultBuildingColor="#36454F"
89
+ defaultDirectoryColor="#111827"
90
+ enableZoom={true}
91
+ />
92
+ );
93
+ },
94
+ };
95
+
96
+ // Story with directory highlighting
97
+ export const DirectoryHighlighting: Story = {
98
+ args: {
99
+ cityData: createSampleCityData(),
100
+ highlightLayers: [
101
+ {
102
+ id: 'test-directory',
103
+ name: 'Test Files',
104
+ enabled: true,
105
+ color: '#f59e0b',
106
+ priority: 1,
107
+ items: [
108
+ { path: 'tests', type: 'directory' },
109
+ { path: '__tests__', type: 'directory' },
110
+ ],
111
+ },
112
+ ],
113
+ showLayerControls: true,
114
+ fullSize: true,
115
+ enableZoom: true,
116
+ },
117
+ };
118
+
119
+ // Story with selective rendering
120
+ export const SelectiveRendering: Story = {
121
+ args: {
122
+ cityData: createSampleCityData(),
123
+ selectiveRender: {
124
+ mode: 'filter',
125
+ directories: new Set(['src', 'tests']),
126
+ },
127
+ fullSize: true,
128
+ enableZoom: true,
129
+ },
130
+ };
131
+
132
+ // Story with subdirectory mode
133
+ export const SubdirectoryMode: Story = {
134
+ args: {
135
+ cityData: createSampleCityData(),
136
+ subdirectoryMode: {
137
+ enabled: true,
138
+ rootPath: 'src',
139
+ autoCenter: true,
140
+ },
141
+ fullSize: true,
142
+ enableZoom: true,
143
+ },
144
+ };
145
+
146
+ // Interactive story with hover and click callbacks
147
+ export const Interactive: Story = {
148
+ render: function RenderInteractive() {
149
+ const [hoveredInfo, setHoveredInfo] = useState<string>('');
150
+ const [clickedPath, setClickedPath] = useState<string>('');
151
+
152
+ return (
153
+ <div style={{ position: 'relative', width: '100%', height: '100%' }}>
154
+ <ArchitectureMapHighlightLayers
155
+ cityData={createSampleCityData()}
156
+ fullSize={true}
157
+ enableZoom={true}
158
+ onHover={info => {
159
+ if (info.hoveredBuilding) {
160
+ setHoveredInfo(`File: ${info.hoveredBuilding.path}`);
161
+ } else if (info.hoveredDistrict) {
162
+ setHoveredInfo(`Directory: ${info.hoveredDistrict.path || '/'}`);
163
+ } else {
164
+ setHoveredInfo('');
165
+ }
166
+ }}
167
+ onFileClick={(path, type) => {
168
+ setClickedPath(`Clicked: ${type} - ${path}`);
169
+ }}
170
+ />
171
+ <div
172
+ style={{
173
+ position: 'absolute',
174
+ top: 20,
175
+ left: 20,
176
+ color: 'white',
177
+ backgroundColor: 'rgba(0, 0, 0, 0.7)',
178
+ padding: '10px',
179
+ borderRadius: '4px',
180
+ fontFamily: 'monospace',
181
+ }}
182
+ >
183
+ <div>{hoveredInfo || 'Hover over elements'}</div>
184
+ {clickedPath && <div>{clickedPath}</div>}
185
+ </div>
186
+ </div>
187
+ );
188
+ },
189
+ };
190
+
191
+ // Story with abstraction layer
192
+ export const WithAbstractionLayer: Story = {
193
+ args: {
194
+ cityData: createSampleCityData(),
195
+ highlightLayers: [
196
+ {
197
+ id: 'directory-abstraction',
198
+ name: 'Directory Abstraction',
199
+ enabled: true,
200
+ color: '#1e40af',
201
+ priority: 0,
202
+ items: [],
203
+ // @ts-expect-error - abstraction layer specific properties
204
+ abstractionLayer: true,
205
+ abstractionConfig: {
206
+ maxZoomLevel: 2.0,
207
+ minPercentage: 0.02,
208
+ backgroundColor: '#1e40af',
209
+ allowRootAbstraction: false,
210
+ },
211
+ },
212
+ ],
213
+ fullSize: true,
214
+ enableZoom: true,
215
+ },
216
+ };
217
+
218
+ // Story with custom rendering strategies
219
+ export const CustomRenderStrategies: Story = {
220
+ args: {
221
+ cityData: createSampleCityData(),
222
+ highlightLayers: [
223
+ {
224
+ id: 'glow-effect',
225
+ name: 'Glow Effect',
226
+ enabled: true,
227
+ color: '#fbbf24',
228
+ priority: 1,
229
+ items: [
230
+ {
231
+ path: 'src/index.ts',
232
+ type: 'file',
233
+ renderStrategy: 'glow',
234
+ },
235
+ ],
236
+ },
237
+ {
238
+ id: 'pattern-fill',
239
+ name: 'Pattern Fill',
240
+ enabled: true,
241
+ color: '#8b5cf6',
242
+ priority: 2,
243
+ items: [
244
+ {
245
+ path: 'package.json',
246
+ type: 'file',
247
+ renderStrategy: 'pattern',
248
+ },
249
+ ],
250
+ },
251
+ {
252
+ id: 'covered-directories',
253
+ name: 'Covered Directories',
254
+ enabled: true,
255
+ color: '#06b6d4',
256
+ priority: 3,
257
+ items: [
258
+ {
259
+ path: 'node_modules',
260
+ type: 'directory',
261
+ renderStrategy: 'cover',
262
+ coverOptions: {
263
+ text: 'Dependencies',
264
+ backgroundColor: '#06b6d4',
265
+ opacity: 0.8,
266
+ borderRadius: 4,
267
+ },
268
+ },
269
+ ],
270
+ },
271
+ ],
272
+ showLayerControls: true,
273
+ fullSize: true,
274
+ enableZoom: true,
275
+ },
276
+ };
277
+
278
+ // Story with grid display
279
+ export const WithGrid: Story = {
280
+ args: {
281
+ cityData: createSampleCityData(),
282
+ showGrid: true,
283
+ showFileNames: true,
284
+ fullSize: true,
285
+ enableZoom: true,
286
+ },
287
+ };
288
+
289
+ // Story with transformations
290
+ export const WithTransformations: Story = {
291
+ args: {
292
+ cityData: createSampleCityData(),
293
+ transform: {
294
+ rotation: 90,
295
+ flipHorizontal: false,
296
+ flipVertical: false,
297
+ },
298
+ fullSize: true,
299
+ enableZoom: true,
300
+ },
301
+ };
302
+
303
+ // Story with border radius
304
+ export const WithBorderRadius: Story = {
305
+ args: {
306
+ cityData: createSampleCityData(),
307
+ buildingBorderRadius: 4,
308
+ districtBorderRadius: 8,
309
+ fullSize: true,
310
+ enableZoom: true,
311
+ },
312
+ };