@shumoku/renderer 0.2.3 → 0.2.5

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.
@@ -4,7 +4,9 @@
4
4
  */
5
5
  import type { LayoutResult, NetworkGraph } from '@shumoku/core';
6
6
  import type { HTMLRendererOptions } from '../types.js';
7
+ import { type NavigationState } from './navigation.js';
7
8
  export type { InteractiveInstance, InteractiveOptions } from '../types.js';
9
+ export type { NavigationState, SheetInfo } from './navigation.js';
8
10
  export { initInteractive } from './runtime.js';
9
11
  /**
10
12
  * Set the IIFE content for standalone HTML pages
@@ -15,9 +17,32 @@ export declare function setIIFE(iife: string): void;
15
17
  */
16
18
  export declare function getIIFE(): string;
17
19
  export interface RenderOptions extends HTMLRendererOptions {
20
+ /**
21
+ * Enable hierarchical navigation UI
22
+ */
23
+ hierarchical?: boolean;
24
+ /**
25
+ * Current sheet ID for hierarchical rendering
26
+ */
27
+ currentSheet?: string;
28
+ /**
29
+ * Navigation state for hierarchical diagrams
30
+ */
31
+ navigation?: NavigationState;
18
32
  }
19
33
  /**
20
34
  * Render a complete standalone HTML page from NetworkGraph
21
35
  */
22
36
  export declare function render(graph: NetworkGraph, layout: LayoutResult, options?: RenderOptions): string;
37
+ /**
38
+ * Sheet data for hierarchical rendering
39
+ */
40
+ export interface SheetData {
41
+ graph: NetworkGraph;
42
+ layout: LayoutResult;
43
+ }
44
+ /**
45
+ * Render a hierarchical HTML page with multiple embedded sheets
46
+ */
47
+ export declare function renderHierarchical(sheets: Map<string, SheetData>, options?: RenderOptions): string;
23
48
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/html/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAK9C;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,MAAM,WAAW,aAAc,SAAQ,mBAAmB;CAAG;AAO7D;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAOjG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/html/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAA4B,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEzF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,iBAAiB,CAAA;AAExB,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAE1E,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAK9C;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,MAAM,WAAW,aAAc,SAAQ,mBAAmB;IACxD;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE,eAAe,CAAA;CAC7B;AAQD;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAmBjG;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,YAAY,CAAA;CACrB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAC9B,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAgDR"}
@@ -3,6 +3,7 @@
3
3
  * Generates standalone interactive HTML pages from NetworkGraph
4
4
  */
5
5
  import { SVGRenderer } from '../svg.js';
6
+ import { generateNavigationToolbar, getNavigationScript, getNavigationStyles, } from './navigation.js';
6
7
  // Re-export runtime for direct usage
7
8
  export { initInteractive } from './runtime.js';
8
9
  // IIFE content - will be set by consumer
@@ -22,16 +23,133 @@ export function getIIFE() {
22
23
  const DEFAULT_OPTIONS = {
23
24
  branding: true,
24
25
  toolbar: true,
26
+ hierarchical: false,
25
27
  };
26
28
  /**
27
29
  * Render a complete standalone HTML page from NetworkGraph
28
30
  */
29
31
  export function render(graph, layout, options) {
30
32
  const opts = { ...DEFAULT_OPTIONS, ...options };
33
+ // Auto-detect hierarchical mode if not explicitly set
34
+ if (options?.hierarchical === undefined) {
35
+ opts.hierarchical = hasHierarchicalContent(graph);
36
+ }
31
37
  const svgRenderer = new SVGRenderer({ renderMode: 'interactive' });
32
38
  const svg = svgRenderer.render(graph, layout);
33
39
  const title = options?.title || graph.name || 'Network Diagram';
34
- return generateHtml(svg, title, opts);
40
+ // Build navigation state if hierarchical
41
+ let navigation = options?.navigation;
42
+ if (!navigation && opts.hierarchical && isHierarchicalGraph(graph)) {
43
+ navigation = buildNavigationState(graph, opts.currentSheet);
44
+ }
45
+ return generateHtml(svg, title, { ...opts, navigation });
46
+ }
47
+ /**
48
+ * Render a hierarchical HTML page with multiple embedded sheets
49
+ */
50
+ export function renderHierarchical(sheets, options) {
51
+ const opts = { ...DEFAULT_OPTIONS, ...options, hierarchical: true };
52
+ const sheetSvgs = new Map();
53
+ const sheetInfos = new Map();
54
+ const rootSheet = sheets.get('root');
55
+ // Render child sheets for navigation (detail view when clicking subgraphs)
56
+ for (const [sheetId, data] of sheets) {
57
+ if (sheetId === 'root')
58
+ continue; // Skip root for now
59
+ // Render child sheet
60
+ const svgRenderer = new SVGRenderer({ renderMode: 'interactive', sheetId });
61
+ const svg = svgRenderer.render(data.graph, data.layout);
62
+ sheetSvgs.set(sheetId, svg);
63
+ sheetInfos.set(sheetId, {
64
+ id: sheetId,
65
+ label: data.graph.name || sheetId,
66
+ parentId: 'root',
67
+ });
68
+ }
69
+ // Render root sheet (ELK handles hierarchical layout natively, no embedding needed)
70
+ if (rootSheet) {
71
+ const rootRenderer = new SVGRenderer({
72
+ renderMode: 'interactive',
73
+ sheetId: 'root',
74
+ });
75
+ const rootSvg = rootRenderer.render(rootSheet.graph, rootSheet.layout);
76
+ sheetSvgs.set('root', rootSvg);
77
+ sheetInfos.set('root', {
78
+ id: 'root',
79
+ label: rootSheet.graph.name || 'root',
80
+ parentId: undefined,
81
+ });
82
+ }
83
+ // Get title from root sheet
84
+ const title = options?.title || rootSheet?.graph.name || 'Network Diagram';
85
+ // Build navigation state
86
+ const navigation = {
87
+ currentSheet: 'root',
88
+ breadcrumb: ['root'],
89
+ sheets: sheetInfos,
90
+ };
91
+ return generateHierarchicalHtml(sheetSvgs, title, { ...opts, navigation });
92
+ }
93
+ /**
94
+ * Check if graph is a hierarchical graph
95
+ */
96
+ function isHierarchicalGraph(graph) {
97
+ return 'sheets' in graph || 'breadcrumb' in graph;
98
+ }
99
+ /**
100
+ * Check if graph has hierarchical content (subgraphs with file/pins)
101
+ */
102
+ function hasHierarchicalContent(graph) {
103
+ if (isHierarchicalGraph(graph))
104
+ return true;
105
+ if (!graph.subgraphs)
106
+ return false;
107
+ return graph.subgraphs.some((sg) => sg.file || (sg.pins && sg.pins.length > 0));
108
+ }
109
+ /**
110
+ * Build navigation state from hierarchical graph
111
+ */
112
+ function buildNavigationState(graph, currentSheet) {
113
+ const sheets = new Map();
114
+ // Add root
115
+ sheets.set('root', {
116
+ id: 'root',
117
+ label: graph.name || 'Overview',
118
+ });
119
+ // Add sheets from subgraphs
120
+ if (graph.subgraphs) {
121
+ for (const subgraph of graph.subgraphs) {
122
+ if (subgraph.file) {
123
+ sheets.set(subgraph.id, {
124
+ id: subgraph.id,
125
+ label: subgraph.label,
126
+ parentId: 'root',
127
+ });
128
+ }
129
+ }
130
+ }
131
+ // Add nested sheets
132
+ if (graph.sheets) {
133
+ for (const [id, sheet] of graph.sheets) {
134
+ if (!sheets.has(id)) {
135
+ sheets.set(id, {
136
+ id,
137
+ label: sheet.name || id,
138
+ parentId: graph.parentSheet,
139
+ });
140
+ }
141
+ }
142
+ }
143
+ // Build breadcrumb
144
+ const breadcrumb = graph.breadcrumb || ['root'];
145
+ if (currentSheet && !breadcrumb.includes(currentSheet)) {
146
+ breadcrumb.push(currentSheet);
147
+ }
148
+ return {
149
+ currentSheet,
150
+ breadcrumb,
151
+ sheets,
152
+ };
35
153
  }
36
154
  function generateHtml(svg, title, options) {
37
155
  const brandingHtml = options.branding
@@ -52,6 +170,17 @@ function generateHtml(svg, title, options) {
52
170
  </div>
53
171
  </div>`
54
172
  : '';
173
+ // Navigation toolbar for hierarchical diagrams
174
+ const navToolbarHtml = options.hierarchical && options.navigation ? generateNavigationToolbar(options.navigation) : '';
175
+ // Navigation styles
176
+ const navStyles = options.hierarchical ? getNavigationStyles() : '';
177
+ // Navigation scripts
178
+ const navScript = options.hierarchical ? getNavigationScript() : '';
179
+ // Calculate container height based on toolbar presence
180
+ const headerHeight = options.toolbar ? 45 : 0;
181
+ const navHeight = options.hierarchical && options.navigation ? 60 : 0;
182
+ const totalHeaderHeight = headerHeight + navHeight;
183
+ const containerHeight = totalHeaderHeight > 0 ? `calc(100vh - ${totalHeaderHeight}px)` : '100vh';
55
184
  return `<!DOCTYPE html>
56
185
  <html>
57
186
  <head>
@@ -67,7 +196,7 @@ function generateHtml(svg, title, options) {
67
196
  .toolbar button { padding: 6px; border: none; background: none; cursor: pointer; border-radius: 4px; color: #666; }
68
197
  .toolbar button:hover { background: #f0f0f0; }
69
198
  .zoom-text { min-width: 50px; text-align: center; font-size: 13px; color: #666; }
70
- .container { position: relative; width: 100%; height: ${options.toolbar ? 'calc(100vh - 45px)' : '100vh'}; overflow: hidden; cursor: grab; background: repeating-conic-gradient(#f8f8f8 0% 25%, transparent 0% 50%) 50% / 20px 20px; }
199
+ .container { position: relative; width: 100%; height: ${containerHeight}; overflow: hidden; cursor: grab; background: repeating-conic-gradient(#f8f8f8 0% 25%, transparent 0% 50%) 50% / 20px 20px; }
71
200
  .container.dragging { cursor: grabbing; }
72
201
  .container > svg { width: 100%; height: 100%; }
73
202
  .branding { position: absolute; bottom: 16px; right: 16px; display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: rgba(255,255,255,0.95); backdrop-filter: blur(8px); border: 1px solid rgba(0,0,0,0.1); border-radius: 8px; font-size: 13px; font-family: system-ui, sans-serif; color: #555; text-decoration: none; transition: all 0.2s; box-shadow: 0 2px 8px rgba(0,0,0,0.1); z-index: 100; }
@@ -78,10 +207,15 @@ function generateHtml(svg, title, options) {
78
207
  .node:hover rect, .node:hover circle, .node:hover polygon { filter: brightness(0.95); }
79
208
  .port { cursor: pointer; }
80
209
  .link-hit-area { cursor: pointer; }
210
+ /* Subgraph click for hierarchical navigation */
211
+ .subgraph[data-has-sheet] { cursor: pointer; }
212
+ .subgraph[data-has-sheet]:hover > rect { filter: brightness(0.95); }
213
+ ${navStyles}
81
214
  </style>
82
215
  </head>
83
216
  <body>
84
217
  ${toolbarHtml}
218
+ ${navToolbarHtml}
85
219
  <div class="container" id="container">
86
220
  ${svg}
87
221
  ${brandingHtml}
@@ -301,9 +435,19 @@ function generateHtml(svg, title, options) {
301
435
  hasMoved = false;
302
436
  });
303
437
 
438
+ // Listen for hierarchical navigation events
439
+ document.addEventListener('shumoku:navigate', function(e) {
440
+ var sheetId = e.detail && e.detail.sheetId;
441
+ if (sheetId) {
442
+ console.log('[Shumoku] Navigate to sheet:', sheetId);
443
+ alert('Navigate to: ' + sheetId + '\\n\\nThis sheet would show the detailed view of this subgraph.');
444
+ }
445
+ });
446
+
304
447
  init();
305
448
  })();
306
449
  </script>
450
+ <script>${navScript}</script>
307
451
  </body>
308
452
  </html>`;
309
453
  }
@@ -315,4 +459,336 @@ function escapeHtml(str) {
315
459
  .replace(/"/g, '&quot;')
316
460
  .replace(/'/g, '&#39;');
317
461
  }
462
+ /**
463
+ * Generate HTML with multiple embedded sheets for hierarchical navigation
464
+ */
465
+ function generateHierarchicalHtml(sheetSvgs, title, options) {
466
+ const brandingHtml = options.branding
467
+ ? `<a class="branding" href="https://shumoku.packof.me" target="_blank" rel="noopener">
468
+ <svg class="branding-icon" viewBox="0 0 1024 1024" fill="none"><rect x="64" y="64" width="896" height="896" rx="200" fill="#7FE4C1"/><g transform="translate(90,40) scale(1.25)"><path fill="#1F2328" d="M380 340H450V505H700V555H510V645H450V645H380Z"/></g></svg>
469
+ <span>Made with Shumoku</span>
470
+ </a>`
471
+ : '';
472
+ const toolbarHtml = options.toolbar
473
+ ? `<div class="toolbar">
474
+ <span class="toolbar-title" id="sheet-title">${escapeHtml(title)}</span>
475
+ <div class="toolbar-buttons">
476
+ <button id="btn-out" title="Zoom Out"><svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-width="2" d="M20 12H4"/></svg></button>
477
+ <span class="zoom-text" id="zoom">100%</span>
478
+ <button id="btn-in" title="Zoom In"><svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg></button>
479
+ <button id="btn-fit" title="Fit"><svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"/></svg></button>
480
+ <button id="btn-reset" title="Reset"><svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg></button>
481
+ </div>
482
+ </div>`
483
+ : '';
484
+ // Build sheet containers
485
+ const sheetContainers = [];
486
+ for (const [sheetId, svg] of sheetSvgs) {
487
+ const isRoot = sheetId === 'root';
488
+ const display = isRoot ? 'block' : 'none';
489
+ sheetContainers.push(`<div class="sheet-container" data-sheet-id="${escapeHtml(sheetId)}" style="display: ${display};">
490
+ ${svg}
491
+ </div>`);
492
+ }
493
+ // Build sheet info JSON for JavaScript
494
+ const sheetInfoJson = {};
495
+ for (const [id, info] of options.navigation?.sheets || []) {
496
+ sheetInfoJson[id] = { label: info.label, parentId: info.parentId };
497
+ }
498
+ const headerHeight = options.toolbar ? 45 : 0;
499
+ const containerHeight = headerHeight > 0 ? `calc(100vh - ${headerHeight}px)` : '100vh';
500
+ return `<!DOCTYPE html>
501
+ <html>
502
+ <head>
503
+ <meta charset="UTF-8">
504
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
505
+ <title>${escapeHtml(title)}</title>
506
+ <style>
507
+ * { margin: 0; padding: 0; box-sizing: border-box; }
508
+ body { background: #f5f5f5; min-height: 100vh; font-family: system-ui, -apple-system, sans-serif; }
509
+ .toolbar { display: flex; align-items: center; justify-content: space-between; padding: 8px 16px; background: white; border-bottom: 1px solid #e5e5e5; }
510
+ .toolbar-title { font-size: 14px; color: #666; display: flex; align-items: center; gap: 8px; }
511
+ .toolbar-buttons { display: flex; gap: 4px; align-items: center; }
512
+ .toolbar button { padding: 6px; border: none; background: none; cursor: pointer; border-radius: 4px; color: #666; }
513
+ .toolbar button:hover { background: #f0f0f0; }
514
+ .zoom-text { min-width: 50px; text-align: center; font-size: 13px; color: #666; }
515
+ .back-btn { display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px; border: 1px solid #ddd; background: white; border-radius: 4px; cursor: pointer; font-size: 13px; color: #555; }
516
+ .back-btn:hover { background: #f5f5f5; }
517
+ .back-btn svg { width: 14px; height: 14px; }
518
+ .container { position: relative; width: 100%; height: ${containerHeight}; overflow: hidden; cursor: grab; background: repeating-conic-gradient(#f8f8f8 0% 25%, transparent 0% 50%) 50% / 20px 20px; }
519
+ .container.dragging { cursor: grabbing; }
520
+ .sheet-container { width: 100%; height: 100%; }
521
+ .sheet-container > svg { width: 100%; height: 100%; }
522
+ .branding { position: absolute; bottom: 16px; right: 16px; display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: rgba(255,255,255,0.95); backdrop-filter: blur(8px); border: 1px solid rgba(0,0,0,0.1); border-radius: 8px; font-size: 13px; font-family: system-ui, sans-serif; color: #555; text-decoration: none; transition: all 0.2s; box-shadow: 0 2px 8px rgba(0,0,0,0.1); z-index: 100; }
523
+ .branding:hover { color: #222; box-shadow: 0 4px 12px rgba(0,0,0,0.15); }
524
+ .branding-icon { width: 16px; height: 16px; border-radius: 3px; flex-shrink: 0; }
525
+ .node { cursor: pointer; }
526
+ .node:hover rect, .node:hover circle, .node:hover polygon { filter: brightness(0.95); }
527
+ .port { cursor: pointer; }
528
+ .link-hit-area { cursor: pointer; }
529
+ .subgraph[data-has-sheet] { cursor: pointer; }
530
+ .subgraph[data-has-sheet]:hover > rect { filter: brightness(0.95); }
531
+ </style>
532
+ </head>
533
+ <body>
534
+ ${toolbarHtml}
535
+ <div class="container" id="container">
536
+ ${sheetContainers.join('\n ')}
537
+ ${brandingHtml}
538
+ </div>
539
+ <script>${INTERACTIVE_IIFE}</script>
540
+ <script>
541
+ (function() {
542
+ var sheetInfo = ${JSON.stringify(sheetInfoJson)};
543
+ var currentSheet = 'root';
544
+ var breadcrumb = ['root'];
545
+ var sheetViewBoxes = {};
546
+ var container = document.getElementById('container');
547
+
548
+ function getActiveSheet() {
549
+ return container.querySelector('.sheet-container[data-sheet-id="' + currentSheet + '"]');
550
+ }
551
+
552
+ function getActiveSvg() {
553
+ var sheet = getActiveSheet();
554
+ return sheet ? sheet.querySelector('svg') : null;
555
+ }
556
+
557
+ function initSheet(sheetId) {
558
+ var sheet = container.querySelector('.sheet-container[data-sheet-id="' + sheetId + '"]');
559
+ if (!sheet) return;
560
+ var svg = sheet.querySelector('svg');
561
+ if (!svg) return;
562
+
563
+ var w = parseFloat(svg.getAttribute('width')) || 800;
564
+ var h = parseFloat(svg.getAttribute('height')) || 600;
565
+ var existing = svg.getAttribute('viewBox');
566
+ var vb;
567
+ if (existing) {
568
+ var p = existing.split(/\\s+|,/).map(Number);
569
+ vb = { x: p[0] || 0, y: p[1] || 0, w: p[2] || w, h: p[3] || h, origX: p[0] || 0, origY: p[1] || 0, origW: p[2] || w, origH: p[3] || h };
570
+ } else {
571
+ vb = { x: 0, y: 0, w: w, h: h, origX: 0, origY: 0, origW: w, origH: h };
572
+ }
573
+ sheetViewBoxes[sheetId] = vb;
574
+
575
+ svg.removeAttribute('width');
576
+ svg.removeAttribute('height');
577
+ svg.style.width = '100%';
578
+ svg.style.height = '100%';
579
+
580
+ // Fit view
581
+ var cw = container.clientWidth || 800;
582
+ var ch = container.clientHeight || 600;
583
+ var scale = Math.min(cw / vb.origW, ch / vb.origH) * 0.9;
584
+ vb.w = cw / scale;
585
+ vb.h = ch / scale;
586
+ vb.x = vb.origX + (vb.origW - vb.w) / 2;
587
+ vb.y = vb.origY + (vb.origH - vb.h) / 2;
588
+ svg.setAttribute('viewBox', vb.x + ' ' + vb.y + ' ' + vb.w + ' ' + vb.h);
589
+
590
+ if (window.ShumokuInteractive) {
591
+ window.ShumokuInteractive.initInteractive({ target: svg, modal: { enabled: true }, tooltip: { enabled: true }, panZoom: { enabled: false } });
592
+ }
593
+ }
594
+
595
+ function updateViewBox() {
596
+ var svg = getActiveSvg();
597
+ var vb = sheetViewBoxes[currentSheet];
598
+ if (!svg || !vb) return;
599
+ svg.setAttribute('viewBox', vb.x + ' ' + vb.y + ' ' + vb.w + ' ' + vb.h);
600
+ var zoomEl = document.getElementById('zoom');
601
+ if (zoomEl) zoomEl.textContent = Math.round(vb.origW / vb.w * 100) + '%';
602
+ }
603
+
604
+ function updateTitle() {
605
+ var titleEl = document.getElementById('sheet-title');
606
+ if (!titleEl) return;
607
+ var info = sheetInfo[currentSheet];
608
+ var label = info ? info.label : currentSheet;
609
+
610
+ if (currentSheet === 'root') {
611
+ titleEl.innerHTML = label;
612
+ } else {
613
+ titleEl.innerHTML = '<button class="back-btn" id="back-btn"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg></button>' + label;
614
+ document.getElementById('back-btn').addEventListener('click', function() {
615
+ navigateToSheet('root');
616
+ });
617
+ }
618
+ }
619
+
620
+ function navigateToSheet(sheetId) {
621
+ if (sheetId === currentSheet) return;
622
+ if (!container.querySelector('.sheet-container[data-sheet-id="' + sheetId + '"]')) {
623
+ console.warn('[Shumoku] Sheet not found:', sheetId);
624
+ return;
625
+ }
626
+
627
+ // Hide current
628
+ var current = getActiveSheet();
629
+ if (current) current.style.display = 'none';
630
+
631
+ // Show new
632
+ currentSheet = sheetId;
633
+ var newSheet = getActiveSheet();
634
+ if (newSheet) {
635
+ newSheet.style.display = 'block';
636
+ if (!sheetViewBoxes[sheetId]) {
637
+ initSheet(sheetId);
638
+ }
639
+ }
640
+
641
+ // Update breadcrumb
642
+ if (sheetId === 'root') {
643
+ breadcrumb = ['root'];
644
+ } else {
645
+ breadcrumb = ['root', sheetId];
646
+ }
647
+
648
+ updateTitle();
649
+ updateViewBox();
650
+ }
651
+
652
+ // Zoom functions
653
+ function zoom(f) {
654
+ var vb = sheetViewBoxes[currentSheet];
655
+ if (!vb) return;
656
+ var cx = vb.x + vb.w / 2, cy = vb.y + vb.h / 2;
657
+ var nw = vb.w / f, nh = vb.h / f;
658
+ var scale = vb.origW / nw;
659
+ if (scale < 0.1 || scale > 10) return;
660
+ vb.w = nw; vb.h = nh; vb.x = cx - nw / 2; vb.y = cy - nh / 2;
661
+ updateViewBox();
662
+ }
663
+
664
+ function fitView() {
665
+ var vb = sheetViewBoxes[currentSheet];
666
+ if (!vb) return;
667
+ var cw = container.clientWidth || 800;
668
+ var ch = container.clientHeight || 600;
669
+ var scale = Math.min(cw / vb.origW, ch / vb.origH) * 0.9;
670
+ vb.w = cw / scale;
671
+ vb.h = ch / scale;
672
+ vb.x = vb.origX + (vb.origW - vb.w) / 2;
673
+ vb.y = vb.origY + (vb.origH - vb.h) / 2;
674
+ updateViewBox();
675
+ }
676
+
677
+ function resetView() {
678
+ var vb = sheetViewBoxes[currentSheet];
679
+ if (!vb) return;
680
+ vb.x = vb.origX; vb.y = vb.origY; vb.w = vb.origW; vb.h = vb.origH;
681
+ updateViewBox();
682
+ }
683
+
684
+ // Toolbar buttons
685
+ var btnIn = document.getElementById('btn-in');
686
+ var btnOut = document.getElementById('btn-out');
687
+ var btnFit = document.getElementById('btn-fit');
688
+ var btnReset = document.getElementById('btn-reset');
689
+ if (btnIn) btnIn.addEventListener('click', function() { zoom(1.2); });
690
+ if (btnOut) btnOut.addEventListener('click', function() { zoom(1/1.2); });
691
+ if (btnFit) btnFit.addEventListener('click', fitView);
692
+ if (btnReset) btnReset.addEventListener('click', resetView);
693
+
694
+ // Mouse drag
695
+ var drag = { active: false, x: 0, y: 0 };
696
+
697
+ container.addEventListener('mousedown', function(e) {
698
+ if (e.button === 0) {
699
+ var vb = sheetViewBoxes[currentSheet];
700
+ if (!vb) return;
701
+ drag = { active: true, x: e.clientX, y: e.clientY, vx: vb.x, vy: vb.y };
702
+ container.classList.add('dragging');
703
+ }
704
+ });
705
+
706
+ document.addEventListener('mousemove', function(e) {
707
+ if (!drag.active) return;
708
+ var vb = sheetViewBoxes[currentSheet];
709
+ if (!vb) return;
710
+ var sx = vb.w / container.clientWidth;
711
+ var sy = vb.h / container.clientHeight;
712
+ vb.x = drag.vx - (e.clientX - drag.x) * sx;
713
+ vb.y = drag.vy - (e.clientY - drag.y) * sy;
714
+ updateViewBox();
715
+ });
716
+
717
+ document.addEventListener('mouseup', function() {
718
+ drag.active = false;
719
+ container.classList.remove('dragging');
720
+ });
721
+
722
+ // Wheel zoom
723
+ container.addEventListener('wheel', function(e) {
724
+ e.preventDefault();
725
+ var vb = sheetViewBoxes[currentSheet];
726
+ if (!vb) return;
727
+ var rect = container.getBoundingClientRect();
728
+ var mx = (e.clientX - rect.left) / rect.width;
729
+ var my = (e.clientY - rect.top) / rect.height;
730
+ var px = vb.x + vb.w * mx, py = vb.y + vb.h * my;
731
+ var f = e.deltaY > 0 ? 1/1.2 : 1.2;
732
+ var nw = vb.w / f, nh = vb.h / f;
733
+ var scale = vb.origW / nw;
734
+ if (scale < 0.1 || scale > 10) return;
735
+ vb.w = nw; vb.h = nh; vb.x = px - nw * mx; vb.y = py - nh * my;
736
+ updateViewBox();
737
+ }, { passive: false });
738
+
739
+ // Navigation event listener
740
+ document.addEventListener('shumoku:navigate', function(e) {
741
+ var sheetId = e.detail && e.detail.sheetId;
742
+ if (sheetId) {
743
+ navigateToSheet(sheetId);
744
+ }
745
+ });
746
+
747
+ // Touch support (simplified)
748
+ var touch1 = null;
749
+ var hasMoved = false;
750
+
751
+ container.addEventListener('touchstart', function(e) {
752
+ if (e.target.closest && e.target.closest('.branding')) return;
753
+ if (e.touches.length === 1) {
754
+ var vb = sheetViewBoxes[currentSheet];
755
+ if (vb) {
756
+ touch1 = { x: e.touches[0].clientX, y: e.touches[0].clientY, vx: vb.x, vy: vb.y };
757
+ hasMoved = false;
758
+ }
759
+ }
760
+ }, { passive: false });
761
+
762
+ container.addEventListener('touchmove', function(e) {
763
+ if (e.target.closest && e.target.closest('.branding')) return;
764
+ if (e.touches.length === 1 && touch1) {
765
+ var vb = sheetViewBoxes[currentSheet];
766
+ if (!vb) return;
767
+ var dx = e.touches[0].clientX - touch1.x;
768
+ var dy = e.touches[0].clientY - touch1.y;
769
+ if (!hasMoved && Math.hypot(dx, dy) > 8) hasMoved = true;
770
+ if (hasMoved) {
771
+ e.preventDefault();
772
+ var sx = vb.w / container.clientWidth;
773
+ var sy = vb.h / container.clientHeight;
774
+ vb.x = touch1.vx - dx * sx;
775
+ vb.y = touch1.vy - dy * sy;
776
+ updateViewBox();
777
+ }
778
+ }
779
+ }, { passive: false });
780
+
781
+ container.addEventListener('touchend', function() {
782
+ touch1 = null;
783
+ hasMoved = false;
784
+ });
785
+
786
+ // Initialize root sheet
787
+ initSheet('root');
788
+ updateTitle();
789
+ })();
790
+ </script>
791
+ </body>
792
+ </html>`;
793
+ }
318
794
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/html/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAIvC,qCAAqC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAE9C,yCAAyC;AACzC,IAAI,gBAAgB,GAAG,EAAE,CAAA;AAEzB;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,gBAAgB,GAAG,IAAI,CAAA;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO;IACrB,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAID,MAAM,eAAe,GAAG;IACtB,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;CACd,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,KAAmB,EAAE,MAAoB,EAAE,OAAuB;IACvF,MAAM,IAAI,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,EAAE,CAAA;IAC/C,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAA;IAClE,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAC7C,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC,IAAI,IAAI,iBAAiB,CAAA;IAE/D,OAAO,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,IAA+B,CAAC,CAAA;AAClE,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,KAAa,EAAE,OAAgC;IAChF,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ;QACnC,CAAC,CAAC;;;SAGG;QACL,CAAC,CAAC,EAAE,CAAA;IAEN,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO;QACjC,CAAC,CAAC;kCAC4B,UAAU,CAAC,KAAK,CAAC;;;;;;;;SAQ1C;QACL,CAAC,CAAC,EAAE,CAAA;IAEN,OAAO;;;;;WAKE,UAAU,CAAC,KAAK,CAAC;;;;;;;;;;4DAUgC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,OAAO;;;;;;;;;;;;;;IAcxG,WAAW;;MAET,GAAG;MACH,YAAY;;YAEN,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA2NpB,CAAA;AACR,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AAC3B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/html/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,GAGpB,MAAM,iBAAiB,CAAA;AAKxB,qCAAqC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAE9C,yCAAyC;AACzC,IAAI,gBAAgB,GAAG,EAAE,CAAA;AAEzB;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,gBAAgB,GAAG,IAAI,CAAA;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO;IACrB,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAmBD,MAAM,eAAe,GAAG;IACtB,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;IACb,YAAY,EAAE,KAAK;CACpB,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,KAAmB,EAAE,MAAoB,EAAE,OAAuB;IACvF,MAAM,IAAI,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,EAAE,CAAA;IAE/C,sDAAsD;IACtD,IAAI,OAAO,EAAE,YAAY,KAAK,SAAS,EAAE,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAA;IACnD,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAA;IAClE,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAC7C,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC,IAAI,IAAI,iBAAiB,CAAA;IAE/D,yCAAyC;IACzC,IAAI,UAAU,GAAgC,OAAO,EAAE,UAAU,CAAA;IACjE,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QACnE,UAAU,GAAG,oBAAoB,CAAC,KAAiC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;IACzF,CAAC;IAED,OAAO,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,UAAU,EAA6B,CAAC,CAAA;AACrF,CAAC;AAUD;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAA8B,EAC9B,OAAuB;IAEvB,MAAM,IAAI,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAA;IAEnE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC3C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAA;IAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAEpC,2EAA2E;IAC3E,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;QACrC,IAAI,OAAO,KAAK,MAAM;YAAE,SAAQ,CAAC,oBAAoB;QAErD,qBAAqB;QACrB,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAA;QAC3E,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QACvD,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QAC3B,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE;YACtB,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO;YACjC,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAA;IACJ,CAAC;IAED,oFAAoF;IACpF,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,YAAY,GAAG,IAAI,WAAW,CAAC;YACnC,UAAU,EAAE,aAAa;YACzB,OAAO,EAAE,MAAM;SAChB,CAAC,CAAA;QACF,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;QACtE,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC9B,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE;YACrB,EAAE,EAAE,MAAM;YACV,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM;YACrC,QAAQ,EAAE,SAAS;SACpB,CAAC,CAAA;IACJ,CAAC;IAED,4BAA4B;IAC5B,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,KAAK,CAAC,IAAI,IAAI,iBAAiB,CAAA;IAE1E,yBAAyB;IACzB,MAAM,UAAU,GAAoB;QAClC,YAAY,EAAE,MAAM;QACpB,UAAU,EAAE,CAAC,MAAM,CAAC;QACpB,MAAM,EAAE,UAAU;KACnB,CAAA;IAED,OAAO,wBAAwB,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,UAAU,EAA6B,CAAC,CAAA;AACvG,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,KAAmB;IAC9C,OAAO,QAAQ,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,CAAA;AACnD,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,KAAmB;IACjD,IAAI,mBAAmB,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3C,IAAI,CAAC,KAAK,CAAC,SAAS;QAAE,OAAO,KAAK,CAAA;IAClC,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;AACjF,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC3B,KAA+B,EAC/B,YAAqB;IAErB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAqB,CAAA;IAE3C,WAAW;IACX,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE;QACjB,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,UAAU;KAChC,CAAC,CAAA;IAEF,4BAA4B;IAC5B,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACvC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAClB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE;oBACtB,EAAE,EAAE,QAAQ,CAAC,EAAE;oBACf,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,QAAQ,EAAE,MAAM;iBACjB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACpB,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE;oBACb,EAAE;oBACF,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;oBACvB,QAAQ,EAAE,KAAK,CAAC,WAAW;iBAC5B,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,CAAA;IAC/C,IAAI,YAAY,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACvD,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IAC/B,CAAC;IAED,OAAO;QACL,YAAY;QACZ,UAAU;QACV,MAAM;KACP,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,KAAa,EAAE,OAAgC;IAChF,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ;QACnC,CAAC,CAAC;;;SAGG;QACL,CAAC,CAAC,EAAE,CAAA;IAEN,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO;QACjC,CAAC,CAAC;kCAC4B,UAAU,CAAC,KAAK,CAAC;;;;;;;;SAQ1C;QACL,CAAC,CAAC,EAAE,CAAA;IAEN,+CAA+C;IAC/C,MAAM,cAAc,GAClB,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,yBAAyB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAEjG,oBAAoB;IACpB,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAEnE,qBAAqB;IACrB,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAEnE,uDAAuD;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACrE,MAAM,iBAAiB,GAAG,YAAY,GAAG,SAAS,CAAA;IAClD,MAAM,eAAe,GAAG,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,iBAAiB,KAAK,CAAC,CAAC,CAAC,OAAO,CAAA;IAEhG,OAAO;;;;;WAKE,UAAU,CAAC,KAAK,CAAC;;;;;;;;;;4DAUgC,eAAe;;;;;;;;;;;;;;MAcrE,SAAS;;;;IAIX,WAAW;IACX,cAAc;;MAEZ,GAAG;MACH,YAAY;;YAEN,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAmOhB,SAAS;;QAEb,CAAA;AACR,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AAC3B,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB,CAC/B,SAA8B,EAC9B,KAAa,EACb,OAAgC;IAEhC,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ;QACnC,CAAC,CAAC;;;SAGG;QACL,CAAC,CAAC,EAAE,CAAA;IAEN,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO;QACjC,CAAC,CAAC;mDAC6C,UAAU,CAAC,KAAK,CAAC;;;;;;;;SAQ3D;QACL,CAAC,CAAC,EAAE,CAAA;IAEN,yBAAyB;IACzB,MAAM,eAAe,GAAa,EAAE,CAAA;IACpC,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,OAAO,KAAK,MAAM,CAAA;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAA;QACzC,eAAe,CAAC,IAAI,CAClB,+CAA+C,UAAU,CAAC,OAAO,CAAC,qBAAqB,OAAO;UAC1F,GAAG;aACA,CACR,CAAA;IACH,CAAC;IAED,uCAAuC;IACvC,MAAM,aAAa,GAAyD,EAAE,CAAA;IAC9E,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,OAAO,CAAC,UAAU,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;QAC1D,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAA;IACpE,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7C,MAAM,eAAe,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAA;IAEtF,OAAO;;;;;WAKE,UAAU,CAAC,KAAK,CAAC;;;;;;;;;;;;;4DAagC,eAAe;;;;;;;;;;;;;;;;IAgBvE,WAAW;;MAET,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC;MAC9B,YAAY;;YAEN,gBAAgB;;;wBAGJ,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA0P7C,CAAA;AACR,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Navigation UI for hierarchical network diagrams
3
+ * Provides breadcrumb, tabs, and back button for sheet navigation
4
+ */
5
+ /**
6
+ * Navigation state for hierarchical diagrams
7
+ */
8
+ export interface NavigationState {
9
+ /**
10
+ * Current sheet ID (undefined = root)
11
+ */
12
+ currentSheet?: string;
13
+ /**
14
+ * Breadcrumb path from root to current sheet
15
+ */
16
+ breadcrumb: string[];
17
+ /**
18
+ * Available sheets
19
+ */
20
+ sheets: Map<string, SheetInfo>;
21
+ }
22
+ /**
23
+ * Information about a sheet
24
+ */
25
+ export interface SheetInfo {
26
+ id: string;
27
+ label: string;
28
+ parentId?: string;
29
+ }
30
+ /**
31
+ * Generate breadcrumb HTML
32
+ */
33
+ export declare function generateBreadcrumb(state: NavigationState): string;
34
+ /**
35
+ * Generate tab navigation HTML for sibling sheets
36
+ */
37
+ export declare function generateTabs(state: NavigationState, siblingIds: string[]): string;
38
+ /**
39
+ * Generate back button HTML
40
+ */
41
+ export declare function generateBackButton(state: NavigationState): string;
42
+ /**
43
+ * Generate complete navigation toolbar HTML
44
+ */
45
+ export declare function generateNavigationToolbar(state: NavigationState, siblingIds?: string[]): string;
46
+ /**
47
+ * Get CSS styles for navigation components
48
+ */
49
+ export declare function getNavigationStyles(): string;
50
+ /**
51
+ * Get JavaScript code for navigation event handling
52
+ */
53
+ export declare function getNavigationScript(): string;
54
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/html/navigation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,UAAU,EAAE,MAAM,EAAE,CAAA;IAEpB;;OAEG;IACH,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAajE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAYjF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAajE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,eAAe,EACtB,UAAU,GAAE,MAAM,EAAO,GACxB,MAAM,CAYR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAiF5C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAkD5C"}