/** * ds-icon-list.js * Icon gallery and management * Browse and export icons from the design system */ export default class IconList extends HTMLElement { constructor() { super(); this.icons = [ { id: 'check', name: 'Check', category: 'Status', svg: '✓', tags: ['status', 'success', 'validation'] }, { id: 'x', name: 'Close', category: 'Status', svg: '✕', tags: ['status', 'error', 'dismiss'] }, { id: 'info', name: 'Info', category: 'Status', svg: 'ⓘ', tags: ['status', 'information', 'help'] }, { id: 'warning', name: 'Warning', category: 'Status', svg: '⚠', tags: ['status', 'warning', 'alert'] }, { id: 'arrow-right', name: 'Arrow Right', category: 'Navigation', svg: '→', tags: ['navigation', 'direction', 'next'] }, { id: 'arrow-left', name: 'Arrow Left', category: 'Navigation', svg: '←', tags: ['navigation', 'direction', 'back'] }, { id: 'arrow-up', name: 'Arrow Up', category: 'Navigation', svg: '↑', tags: ['navigation', 'direction', 'up'] }, { id: 'arrow-down', name: 'Arrow Down', category: 'Navigation', svg: '↓', tags: ['navigation', 'direction', 'down'] }, { id: 'search', name: 'Search', category: 'Actions', svg: '🔍', tags: ['action', 'search', 'find'] }, { id: 'settings', name: 'Settings', category: 'Actions', svg: '⚙', tags: ['action', 'settings', 'config'] }, { id: 'download', name: 'Download', category: 'Actions', svg: '⬇', tags: ['action', 'download', 'save'] }, { id: 'upload', name: 'Upload', category: 'Actions', svg: '⬆', tags: ['action', 'upload', 'import'] }, ]; this.selectedCategory = 'All'; this.searchTerm = ''; } connectedCallback() { this.render(); this.setupEventListeners(); } render() { this.innerHTML = `

Icon Library

Browse and manage icon assets

${this.renderIconCards()}

Export Options

`; } renderIconCards() { let filtered = this.icons; if (this.selectedCategory !== 'All') { filtered = filtered.filter(i => i.category === this.selectedCategory); } if (this.searchTerm) { const term = this.searchTerm.toLowerCase(); filtered = filtered.filter(i => i.name.toLowerCase().includes(term) || i.id.toLowerCase().includes(term) || i.tags.some(t => t.includes(term)) ); } return filtered.map(icon => `
${icon.svg}
${icon.name}
${icon.id}
${icon.category}
`).join(''); } setupEventListeners() { // Search input const searchInput = this.querySelector('#icon-search'); if (searchInput) { searchInput.addEventListener('input', (e) => { this.searchTerm = e.target.value; this.render(); this.setupEventListeners(); }); } // Category filter const filterSelect = this.querySelector('#icon-filter'); if (filterSelect) { filterSelect.addEventListener('change', (e) => { this.selectedCategory = e.target.value; this.render(); this.setupEventListeners(); }); } // Icon cards (copy on click) this.querySelectorAll('.icon-card').forEach(card => { card.addEventListener('click', () => { const iconId = card.dataset.iconId; navigator.clipboard.writeText(iconId).then(() => { const originalBg = card.style.background; card.style.background = 'var(--vscode-selection)'; setTimeout(() => { card.style.background = originalBg; }, 300); }); }); }); // Export buttons const exportSvgBtn = this.querySelector('#export-svg-btn'); if (exportSvgBtn) { exportSvgBtn.addEventListener('click', () => { this.downloadIcons('svg'); }); } const exportJsonBtn = this.querySelector('#export-json-btn'); if (exportJsonBtn) { exportJsonBtn.addEventListener('click', () => { this.downloadIcons('json'); }); } } downloadIcons(format) { const data = format === 'json' ? JSON.stringify(this.icons, null, 2) : this.generateSVGSheet(); const blob = new Blob([data], { type: format === 'json' ? 'application/json' : 'image/svg+xml' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `icons.${format === 'json' ? 'json' : 'svg'}`; a.click(); URL.revokeObjectURL(url); } generateSVGSheet() { return ` ${this.icons.map((icon, i) => ` ${icon.svg} `).join('')} `; } } customElements.define('ds-icon-list', IconList);