- renombrar openspec/ a _openspec/ (carpeta auxiliar) - mover specs de features a changes/ - crear specs base: arquitectura-limpia, estandares-codigo, nomenclatura - migrar _planificacion/ con design-system y roi-theme-template - agregar especificacion recaptcha anti-spam (proposal, tasks, spec) - corregir rutas y referencias en todas las specs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
13 KiB
📦 EJEMPLOS COMPLETOS Y RECURSOS
Ejemplo 1: Campo de Color con Valor Hex
<div class="col-6">
<label for="primaryColor" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-paint-bucket me-1" style="color: #FF8600;"></i>
Color Primario
</label>
<input type="color" id="primaryColor"
class="form-control form-control-color w-100"
value="#0E2337"
title="Seleccionar color primario">
<small class="text-muted d-block mt-1" id="primaryColorValue">#0E2337</small>
</div>
<script>
const colorInput = document.getElementById('primaryColor');
const colorValue = document.getElementById('primaryColorValue');
colorInput.addEventListener('input', function() {
colorValue.textContent = this.value.toUpperCase();
updatePreview();
});
</script>
Ejemplo 2: Campo de Texto con Icono de Bootstrap
<div class="mb-2">
<label for="iconClass" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-emoji-smile me-1" style="color: #FF8600;"></i>
Clase del icono
<span class="badge bg-secondary" style="font-size: 0.65rem;">Bootstrap Icons</span>
</label>
<input type="text" id="iconClass"
class="form-control form-control-sm"
placeholder="bi bi-star-fill"
value="bi bi-megaphone-fill"
maxlength="50">
<small class="text-muted d-block mt-1">
<i class="bi bi-info-circle me-1"></i>
Ver: <a href="https://icons.getbootstrap.com/" target="_blank"
class="text-decoration-none" style="color: #FF8600;">
Bootstrap Icons <i class="bi bi-box-arrow-up-right"></i>
</a>
</small>
</div>
Ejemplo 3: Textarea con Contador y Progress Bar
<div class="mb-2">
<label for="description" class="form-label small mb-1 fw-semibold" style="color: #495057;">
<i class="bi bi-chat-left-text me-1" style="color: #FF8600;"></i>
Descripción <span class="text-danger">*</span>
<span class="float-end text-muted">
<span id="descriptionCount" class="fw-bold">0</span>/250
</span>
</label>
<textarea id="description"
class="form-control form-control-sm"
rows="3"
maxlength="250"
placeholder="Escribe una descripción atractiva..."
required></textarea>
<div class="progress mt-1" style="height: 3px;">
<div id="descriptionProgress"
class="progress-bar"
role="progressbar"
style="width: 0%; background-color: #FF8600;"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="250"></div>
</div>
</div>
<script>
const textarea = document.getElementById('description');
const counter = document.getElementById('descriptionCount');
const progress = document.getElementById('descriptionProgress');
textarea.addEventListener('input', function() {
const length = this.value.length;
const maxLength = 250;
const percentage = (length / maxLength * 100);
counter.textContent = length;
progress.style.width = percentage + '%';
progress.setAttribute('aria-valuenow', length);
// Cambiar color según el uso
if (percentage > 90) {
progress.style.backgroundColor = '#dc3545'; // Rojo
} else if (percentage > 75) {
progress.style.backgroundColor = '#ffc107'; // Amarillo
} else {
progress.style.backgroundColor = '#FF8600'; // Orange
}
updatePreview();
});
</script>
Template Básico Completo
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin: [Component Name]</title>
<!-- Bootstrap 5.3.2 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/Css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/Font/bootstrap-icons.min.css">
<!-- Poppins Font -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<!-- CSS del proyecto principal -->
<link rel="stylesheet" href="../../Css/style.css">
<style>
body {
font-family: 'Poppins', sans-serif;
background-color: #f8f9fa;
}
/* Fix WordPress .card max-width */
body .card {
max-width: none !important;
}
/* Fix WordPress switches */
body .form-switch .form-check-input[type="checkbox"]::before,
body .form-switch .form-check-input[type="checkbox"]::after {
content: none !important;
display: none !important;
}
body .form-switch .form-check-input[type="checkbox"] {
background-size: contain !important;
background-repeat: no-repeat !important;
background-position: left center !important;
}
body .form-switch .form-check-input[type="checkbox"]:checked {
background-position: right center !important;
}
/* Fix alineación vertical switches */
.form-check.form-switch {
display: flex !important;
align-items: center !important;
}
.form-switch .form-check-label {
line-height: 16px !important;
margin-top: 0 !important;
}
/* Responsive */
@media (max-width: 991px) {
.tab-header { padding: 0.75rem; }
}
</style>
</head>
<body>
<div class="container-fluid py-4" style="max-width: 1400px;">
<!-- Header del Tab -->
<div class="rounded p-4 mb-4 shadow text-white"
style="background: linear-gradient(135deg, #0E2337 0%, #1e3a5f 100%);
border-left: 4px solid #FF8600;">
<div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
<div>
<h3 class="h4 mb-1 fw-bold">
<i class="bi bi-[icon] me-2" style="color: #FF8600;"></i>
Configuración de [Component]
</h3>
<p class="mb-0 small" style="opacity: 0.85;">
[Descripción del componente]
</p>
</div>
<button type="button" class="btn btn-sm btn-outline-light" id="resetDefaults">
<i class="bi bi-arrow-counterclockwise me-1"></i>
Restaurar valores por defecto
</button>
</div>
</div>
<!-- Grid de Contenido -->
<div class="row g-3">
<!-- Columna Izquierda -->
<div class="col-lg-6">
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-palette me-2" style="color: #FF8600;"></i>
Sección 1
</h5>
<!-- Campos -->
</div>
</div>
</div>
<!-- Columna Derecha -->
<div class="col-lg-6">
<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-gear me-2" style="color: #FF8600;"></i>
Sección 2
</h5>
<!-- Campos -->
</div>
</div>
</div>
<!-- Vista Previa -->
<div class="col-12">
<div class="card shadow-sm mb-3" style="border-left: 4px solid #FF8600;">
<div class="card-body">
<h5 class="fw-bold mb-3" style="color: #1e3a5f;">
<i class="bi bi-eye me-2" style="color: #FF8600;"></i>
Vista Previa en Tiempo Real
</h5>
<div id="componentPreview" class="[component-class]">
<!-- HTML idéntico al front-end -->
</div>
<div class="d-flex justify-content-between align-items-center mt-3">
<small class="text-muted">
<i class="bi bi-info-circle me-1"></i>
Los cambios se reflejan en tiempo real
</small>
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-outline-secondary active" id="previewDesktop">
<i class="bi bi-display"></i> Desktop
</button>
<button type="button" class="btn btn-outline-secondary" id="previewMobile">
<i class="bi bi-phone"></i> Mobile
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/Js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('✅ Admin Panel cargado');
loadConfig();
updatePreview();
initializeEventListeners();
});
function initializeEventListeners() {
// Conectar event listeners
}
function updatePreview() {
// Actualizar vista previa
}
function saveConfig() {
// Guardar configuración
}
function loadConfig() {
// Cargar configuración
}
function resetToDefaults() {
if (!confirm('¿Estás seguro de restaurar los valores por defecto?')) {
return;
}
// Reset a defaults
}
</script>
</body>
</html>
Checklist de Implementación
Antes de Empezar
- Leer este manual completo
- Revisar la librería de componentes HTML (
../componentes-html-bootstrap/) - Identificar qué campos necesita el componente
- Determinar si necesita vista previa en tiempo real
Estructura HTML
- Crear el header del tab con gradiente navy + border orange
- Incluir botón "Restaurar valores por defecto"
- Organizar campos en grid de 2 columnas (
col-lg-6) - Agrupar campos relacionados en cards con border-left navy
- Agregar card de vista previa con border-left orange
Formularios
- Todos los labels tienen icono orange
- Labels importantes tienen
fw-semibold - Campos requeridos tienen
<span class="text-danger">*</span> - Color pickers muestran valor hex debajo
- Textareas tienen contador de caracteres + progress bar
- Selects usan
.form-select-sm - Inputs usan
.form-control-sm - Switches tienen icono + strong en label
Vista Previa
- HTML de preview es IDÉNTICO al del front-end
- Se usa clase real del componente (ej:
.top-notification-bar) - NO hay inline styles que sobreescriban el CSS real
- Se cargan los mismos archivos CSS que el front-end
- Botones Desktop/Mobile funcionales
JavaScript
- Función
updatePreview()implementada - Función
saveConfig()guarda en localStorage/JSON - Función
loadConfig()carga al iniciar - Función
resetToDefaults()restaura valores - Event listeners en todos los campos
- Color pickers actualizan el valor hex
- Textareas actualizan contador + progress bar
CSS
- Fix WordPress
.card { max-width: none !important; } - Fix WordPress switches (pseudo-elementos)
- Fix alineación vertical switches
- Responsive breakpoints configurados
Troubleshooting
La vista previa no se ve igual al front-end
Causa: Inline styles sobreescribiendo el CSS real
Solución:
- Verificar que NO haya inline styles en el HTML del preview
- Verificar que se carga
../../Css/style.css - Usar solo la clase del componente real
- Si es necesario, agregar CSS con
!importantSOLO para el border
Los colores no coinciden
Causa: No se están usando los valores correctos
Solución:
- Usar valores hex exactos:
#0E2337,#FF8600, etc. - Verificar que
style.cssdefine las variables:root
El contador de caracteres no funciona
Causa: Event listener no conectado
Solución:
textarea.addEventListener('input', function() {
counter.textContent = this.value.length;
});
El responsive no funciona
Causa: Falta el viewport meta tag
Solución:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Recursos
Bootstrap 5.3.2
- Documentación: https://getbootstrap.com/docs/5.3/
- Components: https://getbootstrap.com/docs/5.3/components/
Bootstrap Icons
- Catálogo: https://icons.getbootstrap.com/
- Búsqueda: Usar el buscador para encontrar iconos
Google Fonts - Poppins
- Pesos usados: 400 (Regular), 500 (Medium), 600 (Semi-Bold), 700 (Bold)