Componente web personalizado para crear controles de cantidad con botones de incremento y decremento, ideal para formularios, carritos de compra y cualquier interfaz que requiera selección numérica.
<!-- Importar el componente -->
<script src="quantity-component/index.js"></script>
<link rel="stylesheet" href="quantity-component/index.css">
<!-- Implementación básica -->
<quantity-component>
<button class="quantity-component-button quantity-component-button-minus"
type="button" data-quantity-button-minus>
<svg>...</svg>
</button>
<input class="quantity-component-input"
type="number"
name="quantity"
value="1"
min="1"
pattern="[0-9]*"
data-quantity-input>
<button class="quantity-component-button quantity-component-button-plus"
type="button" data-quantity-button-plus>
<svg>...</svg>
</button>
</quantity-component>
// Seleccionar el componente
const quantityComponent = document.querySelector('quantity-component');
// Establecer el valor mediante JavaScript
quantityComponent.dataset.value = 3;
// Escuchar cambios en el valor
quantityComponent.addEventListener('value:change', (event) => {
console.log('Nuevo valor:', event.detail.value);
});
Este ejemplo permite establecer la cantidad a cero. El botón de decrementar se desactiva automáticamente cuando se alcanza el valor mínimo.
<quantity-component class="quantity-material">
<button class="quantity-component-button quantity-component-button-minus"
type="button" data-quantity-button-minus>
<svg>...</svg>
</button>
<input class="quantity-component-input"
type="number"
name="quantity"
value="1"
min="0"
pattern="[0-9]*"
data-quantity-input>
<button class="quantity-component-button quantity-component-button-plus"
type="button" data-quantity-button-plus>
<svg>...</svg>
</button>
</quantity-component>
.quantity-material {
--max-width: 120px;
--height: 45px;
--border: none;
--border-radius: 4px;
--button-background: #f5f5f5;
--button-background-hover: #ff9800;
--button-color-hover: white;
--input-background: #f5f5f5;
--button-color: #333;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
}
Historial de eventos: Componente inicializado con valor: 1
<quantity-component class="quantity-rounded">
<!-- Contenido del componente -->
</quantity-component>
.quantity-rounded {
--max-width: 140px;
--height: 45px;
--border: 1px solid rgba(0, 188, 212, 0.5);
--border-radius: 50px;
--button-background: rgba(0, 0, 0, 0.2);
--button-background-hover: #00bcd4;
--button-color: #e0e0e0;
--button-color-hover: white;
--input-background: rgba(0, 0, 0, 0.1);
--input-text-color: #e0e0e0;
}
const quantityComponent = document.querySelector('#rounded-quantity');
const eventLog = document.querySelector('#event-log');
quantityComponent.addEventListener('value:change', function(event) {
const newEntry = `Valor cambiado: ${event.detail.value}`;
eventLog.textContent += `\n${newEntry}`;
});
.quantity-primary {
--max-width: 130px;
--height: 42px;
--border: 1px solid var(--component-primary);
--border-radius: 5px;
--button-background: var(--component-primary);
--button-color: white;
--button-background-hover: var(--component-secondary);
--button-color-hover: white;
--input-background: rgba(0, 0, 0, 0.1);
--input-text-color: var(--text-color);
}
document.querySelector('#submit-form').addEventListener('click', function(e) {
e.preventDefault();
const productName = document.querySelector('#product-name').value;
const quantity = document.querySelector('#form-quantity').dataset.value;
const color = document.querySelector('#product-color').value;
const resultElement = document.querySelector('#form-result');
resultElement.style.display = 'block';
resultElement.innerHTML = `
Producto añadido:
Nombre: ${productName}
Cantidad: ${quantity}
Color: ${color}
`;
// Aquí iría el código para enviar los datos al servidor
});
.quantity-dark {
--max-width: 120px;
--height: 40px;
--border: 1px solid rgba(0, 188, 212, 0.3);
--border-radius: 4px;
--button-background: #333;
--button-color: var(--component-primary);
--button-background-hover: var(--component-primary);
--button-color-hover: white;
--input-background: #333;
--input-text-color: var(--text-color);
}