// Main JavaScript for CodeCanvas // Initialize tooltips for icons function initTooltips() { const tooltipElements = document.querySelectorAll('[data-tooltip]'); tooltipElements.forEach(element => { element.addEventListener('mouseenter', (e) => { const tooltipText = element.getAttribute('data-tooltip'); const tooltip = document.createElement('div'); tooltip.className = 'fixed z-50 px-3 py-2 text-sm bg-gray-900 text-white rounded-lg shadow-lg border border-gray-700 pointer-events-none'; tooltip.textContent = tooltipText; document.body.appendChild(tooltip); const rect = element.getBoundingClientRect(); tooltip.style.left = `${rect.left + rect.width / 2 - tooltip.offsetWidth / 2}px`; tooltip.style.top = `${rect.top - tooltip.offsetHeight - 10}px`; element._tooltip = tooltip; }); element.addEventListener('mouseleave', (e) => { if (element._tooltip) { element._tooltip.remove(); delete element._tooltip; } }); }); } // Dark/Light mode toggle function initThemeToggle() { const themeToggle = document.querySelector('[data-theme-toggle]'); if (!themeToggle) return; themeToggle.addEventListener('click', () => { const html = document.documentElement; const isDark = html.classList.contains('dark'); if (isDark) { html.classList.remove('dark'); localStorage.setItem('theme', 'light'); } else { html.classList.add('dark'); localStorage.setItem('theme', 'dark'); } // Update icon const icon = themeToggle.querySelector('i[data-feather]'); if (icon) { const newIcon = isDark ? 'sun' : 'moon'; icon.setAttribute('data-feather', newIcon); feather.replace(); } }); } // Project statistics from GitHub API async function loadGitHubStats() { try { const response = await fetch('https://api.github.com/repos/tailwindlabs/tailwindcss'); const data = await response.json(); const statsElement = document.querySelector('[data-github-stats]'); if (statsElement) { statsElement.innerHTML = `
${(data.stargazers_count / 1000).toFixed(1)}k
Stars
${data.forks_count}
Forks
${(data.watchers_count / 1000).toFixed(1)}k
Watchers
`; } } catch (error) { console.log('GitHub stats loading failed, using fallback'); } } // Code execution simulation function initCodeRunner() { const runButtons = document.querySelectorAll('[data-run-code]'); runButtons.forEach(button => { button.addEventListener('click', async () => { const originalText = button.textContent; button.disabled = true; button.innerHTML = '
'; // Simulate code execution await new Promise(resolve => setTimeout(resolve, 1500)); button.disabled = false; button.textContent = originalText; // Show success message const notification = document.createElement('div'); notification.className = 'fixed bottom-4 right-4 bg-gradient-to-r from-rose-500 to-pink-500 text-white px-6 py-3 rounded-xl shadow-lg transform transition-all duration-300 translate-y-0 opacity-100'; notification.textContent = 'Code executed successfully!'; document.body.appendChild(notification); setTimeout(() => { notification.classList.add('translate-y-8', 'opacity-0'); setTimeout(() => notification.remove(), 300); }, 3000); }); }); } // Search functionality function initSearch() { const searchInput = document.querySelector('[data-search-input]'); const searchResults = document.querySelector('[data-search-results]'); if (!searchInput || !searchResults) return; let searchTimeout; searchInput.addEventListener('input', (e) => { clearTimeout(searchTimeout); searchTimeout = setTimeout(() => { const query = e.target.value.trim(); if (query.length < 2) { searchResults.classList.add('hidden'); return; } // Simulate search results const results = [ { type: 'file', name: 'main.js', path: '/src/main.js' }, { type: 'component', name: 'Navbar', path: '/components/Navbar.js' }, { type: 'style', name: 'global.css', path: '/styles/global.css' }, { type: 'page', name: 'Dashboard', path: '/pages/dashboard.js' } ]; searchResults.innerHTML = results.map(result => `
${result.name}
${result.path}
`).join(''); searchResults.classList.remove('hidden'); feather.replace(); }, 300); }); // Close search when clicking outside document.addEventListener('click', (e) => { if (!searchInput.contains(e.target) && !searchResults.contains(e.target)) { searchResults.classList.add('hidden'); } }); } // Initialize everything when DOM is loaded document.addEventListener('DOMContentLoaded', () => { // Initialize all features initTooltips(); initThemeToggle(); initCodeRunner(); initSearch(); // Load GitHub stats loadGitHubStats(); // Update feather icons feather.replace(); // Add keyboard shortcuts document.addEventListener('keydown', (e) => { // Ctrl/Cmd + K for search if ((e.ctrlKey || e.metaKey) && e.key === 'k') { e.preventDefault(); const searchInput = document.querySelector('[data-search-input]'); if (searchInput) { searchInput.focus(); } } // Ctrl/Cmd + / for help if ((e.ctrlKey || e.metaKey) && e.key === '/') { e.preventDefault(); alert('Available shortcuts:\n\nCtrl/Cmd + K: Search\nCtrl/Cmd + /: This help\nCtrl/Cmd + S: Save\nCtrl/Cmd + E: New file'); } }); console.log('CodeCanvas initialized successfully! 🎨'); }); // Export functions for component usage window.CodeCanvas = { initTooltips, initThemeToggle, loadGitHubStats, initCodeRunner, initSearch };