color-selector-component
Version:
Web Component para seleccionar colores con estilos personalizados y formAssociated
119 lines (101 loc) • 3 kB
JavaScript
class ColorSelector extends HTMLElement {
static formAssociated = true;
constructor() {
super();
this._internals = this.attachInternals();
this.attachShadow({ mode: 'open' });
this.selectEl = null;
this.colorBox = null;
}
connectedCallback() {
this.render();
}
render() {
const colorsAttr = this.getAttribute('colors');
let colors = [];
try {
if (colorsAttr) {
colors = JSON.parse(colorsAttr);
if (!Array.isArray(colors)) colors = [];
}
} catch {
colors = [];
}
if (colors.length === 0) {
colors = [
{ value: 'red', label: 'Rojo' },
{ value: 'green', label: 'Verde' },
{ value: 'blue', label: 'Azul' },
{ value: 'yellow', label: 'Amarillo' }
];
}
// Obtener width y height o poner valores por defecto
const width = this.getAttribute('width') || '150px';
const height = this.getAttribute('height') || '30px';
this.shadowRoot.innerHTML = `
<style>
.container {
display: flex;
align-items: center;
gap: 10px;
margin: 10px 0;
}
select {
padding: 5px;
font-size: 14px;
width: ${width};
height: ${height};
box-sizing: border-box;
}
.color-box {
width: ${height}; /* Cuadro cuadrado con misma altura que select */
height: ${height};
border: 1px solid #333;
border-radius: 4px;
background-color: #fff;
transition: background-color 0.3s ease;
}
</style>
<div class="container">
<select name="${this.getAttribute('name') || ''}">
<option value="">-- Elige un color --</option>
${colors.map(c => `<option value="${c.value}">${c.label}</option>`).join('')}
</select>
<div class="color-box"></div>
</div>
`;
this.selectEl = this.shadowRoot.querySelector('select');
this.colorBox = this.shadowRoot.querySelector('.color-box');
this.selectEl.addEventListener('change', () => {
const value = this.selectEl.value;
this.colorBox.style.backgroundColor = value || '#fff';
this._internals.setFormValue(value);
});
if (this.hasAttribute('value')) {
this.value = this.getAttribute('value');
}
}
get name() {
return this.getAttribute('name');
}
get form() {
return this._internals.form;
}
get type() {
return 'text';
}
get value() {
return this.selectEl ? this.selectEl.value : '';
}
set value(val) {
if (this.selectEl) {
this.selectEl.value = val;
this.colorBox.style.backgroundColor = val || '#fff';
this._internals.setFormValue(val);
}
}
formResetCallback() {
this.value = '';
}
}
customElements.define('color-selector', ColorSelector);