feat: Make Lucide icons globally available without Stimulus controller

- Replace unpkg CDN with npm package import in application.js
- Add global initialization for all Lucide icons on page load and Turbo events
- Remove dependency on lucide_controller.js and data-controller wrapper
- Icons now work anywhere with simple <i data-lucide="icon-name"></i> syntax
- Bundle size increased to include full icon set but removes controller overhead

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kbe
2025-09-05 11:52:10 +02:00
parent a3689948ae
commit 46c8faf10c
6 changed files with 98 additions and 293 deletions

View File

@@ -6,3 +6,18 @@ import "@hotwired/turbo-rails";
// Import all Stimulus controllers
import "./controllers";
// Import and initialize Lucide icons globally
import { createIcons, icons } from 'lucide';
// Initialize icons globally
function initializeLucideIcons() {
createIcons({ icons });
}
// Run on initial page load
document.addEventListener('DOMContentLoaded', initializeLucideIcons);
// Run on Turbo navigation (Rails 7+ SPA behavior)
document.addEventListener('turbo:render', initializeLucideIcons);
document.addEventListener('turbo:frame-render', initializeLucideIcons);

View File

@@ -1,68 +0,0 @@
import { Controller } from "@hotwired/stimulus"
// Connects to data-controller="lucide"
export default class extends Controller {
static targets = ["icon"]
connect() {
this.initializeIcons()
// Listen for Turbo navigation events to reinitialize icons
document.addEventListener('turbo:render', this.handleTurboRender.bind(this))
document.addEventListener('turbo:frame-render', this.handleTurboFrameRender.bind(this))
}
disconnect() {
// Clean up event listeners
document.removeEventListener('turbo:render', this.handleTurboRender.bind(this))
document.removeEventListener('turbo:frame-render', this.handleTurboFrameRender.bind(this))
}
// Initialize all Lucide icons in the controller scope
initializeIcons() {
if (typeof lucide !== 'undefined') {
// Initialize icons within this controller's element
lucide.createIcons({
element: this.element
})
} else {
console.warn('Lucide not loaded yet, retrying...')
// Retry after a short delay if Lucide hasn't loaded yet
setTimeout(() => this.initializeIcons(), 100)
}
}
// Method to reinitialize icons after dynamic content changes
reinitialize() {
this.initializeIcons()
}
// Method to create a specific icon programmatically
createIcon(iconName, element = null) {
if (typeof lucide !== 'undefined') {
const targetElement = element || this.element
lucide.createIcons({
element: targetElement,
icons: {
[iconName]: lucide[iconName]
}
})
}
}
// Handle Turbo page renders
handleTurboRender() {
// Small delay to ensure DOM is fully updated
setTimeout(() => this.initializeIcons(), 10)
}
// Handle Turbo frame renders
handleTurboFrameRender(event) {
// Initialize icons within the specific frame that was rendered
if (event.detail && event.detail.newFrame) {
lucide.createIcons({
element: event.detail.newFrame
})
}
}
}