File size: 3,300 Bytes
5a81b95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**
 * ╔═══════════════════════════════════════════════════════════════════════════╗
 * β•‘                    MIND MAP VIEW COMPONENT                                β•‘
 * ║═══════════════════════════════════════════════════════════════════════════║
 * β•‘  Hierarchical idea visualization and brainstorming                        β•‘
 * β•‘  Part of the Visual Cortex Layer                                         β•‘
 * β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
 */

import { useMemo } from 'react';
import { MermaidDiagram } from './MermaidDiagram';
import { cn } from '@/lib/utils';

export interface MindMapNode {
  id: string;
  label: string;
  children?: MindMapNode[];
  icon?: string;
  style?: 'default' | 'highlight' | 'warning' | 'success';
}

export interface MindMapViewProps {
  /** Central topic / root node */
  root: MindMapNode;
  /** Diagram title */
  title?: string;
  /** Custom class */
  className?: string;
  /** Callback when rendered */
  onRender?: (svg: string) => void;
}

// Style to color mapping
const STYLE_COLORS: Record<string, string> = {
  default: '#3b82f6',
  highlight: '#f59e0b',
  warning: '#ef4444',
  success: '#22c55e',
};

export function MindMapView({
  root,
  title,
  className,
  onRender,
}: MindMapViewProps) {
  const mermaidCode = useMemo(() => {
    const lines: string[] = ['mindmap'];

    // Recursively build mindmap structure
    const buildNode = (node: MindMapNode, indent: number = 1) => {
      const indentStr = '  '.repeat(indent);
      const icon = node.icon ? `::icon(${node.icon})` : '';

      // Root uses different syntax
      if (indent === 1) {
        lines.push(`${indentStr}root((${node.label}))${icon}`);
      } else {
        // Alternate shapes for visual variety
        const shapes = ['', '()', '[]', '{{}}'];
        const shapeIndex = (indent - 1) % shapes.length;
        const shape = shapes[shapeIndex];

        if (shape === '()') {
          lines.push(`${indentStr}(${node.label})${icon}`);
        } else if (shape === '[]') {
          lines.push(`${indentStr}[${node.label}]${icon}`);
        } else if (shape === '{{}}') {
          lines.push(`${indentStr}{{${node.label}}}${icon}`);
        } else {
          lines.push(`${indentStr}${node.label}${icon}`);
        }
      }

      // Process children
      if (node.children && node.children.length > 0) {
        node.children.forEach(child => {
          buildNode(child, indent + 1);
        });
      }
    };

    buildNode(root);

    return lines.join('\n');
  }, [root]);

  return (
    <div className={cn('mindmap-view', className)}>
      <MermaidDiagram
        code={mermaidCode}
        title={title}
        theme="dark"
        zoomable={true}
        onRender={onRender}
      />
    </div>
  );
}

export default MindMapView;