/** * AnimationLibrary Component - Tasmota Style * * Provides a browsable library of example animations organized by category. * Features: * - Category organization with nested fieldsets * - Search functionality with Tasmota input styling * - Example list items styled as Tasmota buttons * - Load example code into editor on selection * * Requirements: 9.3, 13.1, 8.4 */ (function(window) { 'use strict'; /** * AnimationLibrary - UI component for browsing animation examples */ class AnimationLibrary { /** * Create a new AnimationLibrary * @param {Object} options - Configuration options * @param {string} options.containerId - ID of container element * @param {Function} options.onSelect - Callback when example is selected * @param {boolean} options.collapsed - Start collapsed (default: true) */ constructor(options = {}) { this.options = Object.assign({ containerId: 'animation-library-container', onSelect: null, collapsed: true }, options); this.container = null; this.searchInput = null; this.categoryContainers = {}; this.exampleButtons = []; this.isExpanded = !this.options.collapsed; this.selectedExampleId = null; this._init(); } /** * Initialize the library component * @private */ _init() { this.container = document.getElementById(this.options.containerId); if (!this.container) { console.warn('[AnimationLibrary] Container not found:', this.options.containerId); return; } this._render(); this._bindEvents(); } /** * Render the library UI * @private */ _render() { // Get examples from the global animationExamples const examples = window.animationExamples ? window.animationExamples.getAll() : []; const categories = window.animationExamples ? window.animationExamples.getCategories() : []; // Build HTML let html = ''; // Header with toggle and search (entire row is clickable) html += '