/ src / routes / components / ThemeCustomizer.svelte
ThemeCustomizer.svelte
  1  <script lang="ts">
  2    import { primaryColor } from '$lib/stores';
  3    import { onMount } from 'svelte';
  4    
  5    let isOpen = false;
  6    let colorPicker: HTMLInputElement;
  7    
  8    // Función para abrir el selector de color
  9    function toggleColorPicker() {
 10      if (!isOpen) {
 11        setTimeout(() => {
 12          if (colorPicker) colorPicker.click();
 13        }, 50);
 14      }
 15      isOpen = !isOpen;
 16    }
 17  
 18    // Aplicar el color inmediatamente mientras se mueve el selector
 19    function handleColorChange(event: Event) {
 20      const input = event.target as HTMLInputElement;
 21      const newColor = input.value;
 22      
 23      // Actualizar el store - esto desencadenará la suscripción en stores.ts
 24      // que manejará correctamente los cambios de color para ambos temas
 25      primaryColor.set(newColor);
 26      
 27      // Ya no necesitamos aplicar manualmente las propiedades CSS aquí
 28      // ya que la suscripción en stores.ts se encarga de aplicar los colores
 29      // considerando si estamos en modo oscuro o claro
 30      
 31      // Guardar en localStorage (este paso sigue siendo necesario)
 32      if (typeof window !== 'undefined') {
 33        localStorage.setItem('primaryColor', newColor);
 34      }
 35    }
 36    
 37    // Cerrar el panel al hacer clic fuera
 38    function handleClickOutside(event: MouseEvent) {
 39      const target = event.target as HTMLElement;
 40      if (isOpen && !target.closest('.theme-customizer') && target.id !== 'primary-color') {
 41        isOpen = false;
 42      }
 43    }
 44    
 45    onMount(() => {
 46      document.addEventListener('click', handleClickOutside);
 47      return () => {
 48        document.removeEventListener('click', handleClickOutside);
 49      };
 50    });
 51  </script>
 52  
 53  <div class="theme-customizer">
 54    <button 
 55      class="color-button" 
 56      on:click={toggleColorPicker} 
 57      aria-label="Personalizar color"
 58      style="background-color: {$primaryColor};"
 59    >
 60      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
 61        <circle cx="12" cy="12" r="10"></circle>
 62        <circle cx="12" cy="12" r="6"></circle>
 63        <circle cx="12" cy="12" r="2"></circle>
 64      </svg>
 65    </button>
 66    
 67    <input 
 68      id="primary-color" 
 69      bind:this={colorPicker}
 70      type="color" 
 71      bind:value={$primaryColor} 
 72      on:input={handleColorChange}
 73      class="color-input"
 74    />
 75  </div>
 76  
 77  <style>
 78    .theme-customizer {
 79      position: relative;
 80      display: inline-block;
 81    }
 82    
 83    .color-button {
 84      width: 40px;
 85      height: 40px;
 86      border-radius: 50%;
 87      border: 2px solid white;
 88      cursor: pointer;
 89      display: flex;
 90      align-items: center;
 91      justify-content: center;
 92      color: white;
 93      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
 94      transition: transform 0.2s;
 95    }
 96    
 97    .color-button:hover {
 98      transform: scale(1.05);
 99    }
100    
101    .color-input {
102      position: absolute;
103      top: 0;
104      left: 0;
105      opacity: 0;
106      width: 1px;
107      height: 1px;
108      z-index: -1;
109    }
110  </style>