File size: 3,171 Bytes
ff36e71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { 
  Book, GraduationCap, Microscope, FlaskConical, Calculator, Globe, Music, 
  Palette, PenTool, Pencil, Ruler, Shapes, BookOpen, Library, 
  Code, Cpu, Database, Monitor, Smartphone, Laptop, Server, Terminal, 
  Folder, FileText, File, Image as ImageIcon, Video, Mic, Camera, Archive, Box, Clipboard, 
  Calendar, Clock, CheckCircle, CheckSquare, List, ListTodo, 
  Heart, Star, Award, Zap, Flame, Droplet, Sun, Moon, Cloud, Anchor, Flag, 
  Briefcase, ShoppingCart, Gift, User, Users,
  Activity, AlertTriangle, MessageCircle, Info, Hash, Link, LogOut
} from 'lucide';

// Explicit map to enable tree-shaking while providing string-based access
export const AVAILABLE_ICONS = {
  'book': Book,
  'graduation-cap': GraduationCap,
  'microscope': Microscope,
  'flask-conical': FlaskConical,
  'calculator': Calculator,
  'globe': Globe,
  'music': Music,
  'palette': Palette,
  'pen-tool': PenTool,
  'pencil': Pencil,
  'ruler': Ruler,
  'shapes': Shapes,
  'book-open': BookOpen,
  'library': Library,
  'code': Code,
  'cpu': Cpu,
  'database': Database,
  'monitor': Monitor,
  'smartphone': Smartphone,
  'laptop': Laptop,
  'server': Server,
  'terminal': Terminal,
  'folder': Folder,
  'file-text': FileText,
  'file': File,
  'image': ImageIcon,
  'video': Video,
  'mic': Mic,
  'camera': Camera,
  'archive': Archive,
  'box': Box,
  'clipboard': Clipboard,
  'calendar': Calendar,
  'clock': Clock,
  'check-circle': CheckCircle,
  'check-square': CheckSquare,
  'list': List,
  'list-todo': ListTodo,
  'heart': Heart,
  'star': Star,
  'award': Award,
  'zap': Zap,
  'flame': Flame,
  'droplet': Droplet,
  'sun': Sun,
  'moon': Moon,
  'cloud': Cloud,
  'anchor': Anchor,
  'flag': Flag,
  'briefcase': Briefcase,
  'shopping-cart': ShoppingCart,
  'gift': Gift,
  'user': User,
  'users': Users,
  'activity': Activity,
  'alert-triangle': AlertTriangle,
  'message-circle': MessageCircle,
  'info': Info,
  'hash': Hash,
  'link': Link,
  'log-out': LogOut
};

// Returns an array of all available icon names for the AI to choose from
export const ICON_NAMES = Object.keys(AVAILABLE_ICONS);

/**
 * Renders a Lucide AST node to an SVG string.
 * Lucide AST format: ['tag', { attributes }, [children]]
 */
function renderAst(node) {
  if (!node) return '';
  const [tag, attrs, children] = node;
  
  const attrsString = Object.entries(attrs || {})
    .map(([key, value]) => `${key}="${value}"`)
    .join(' ');
  
  const childrenString = (children || [])
    .map(child => renderAst(child))
    .join('');
    
  return `<${tag} ${attrsString}>${childrenString}</${tag}>`;
}

export function getIconSvg(name, customAttrs = {}) {
  const iconDef = AVAILABLE_ICONS[name] || AVAILABLE_ICONS['folder'];
  
  // In 'lucide' package, the exported icon is an array of child nodes: [ ['path', {d: '...'}], ... ]
  const rootAttrs = {
    xmlns: 'http://www.w3.org/2000/svg',
    width: '24',
    height: '24',
    viewBox: '0 0 24 24',
    fill: 'none',
    stroke: 'currentColor',
    'stroke-width': '2',
    'stroke-linecap': 'round',
    'stroke-linejoin': 'round',
    ...customAttrs
  };
  
  return renderAst(['svg', rootAttrs, iconDef]);
}