Files
roi-theme/_planificacion/01-design-system/09-VISTA-PREVIA-TIEMPO-REAL.md
FrankZamora 0f6387ab46 refactor: reorganizar openspec y planificacion con spec recaptcha
- 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>
2026-01-08 15:30:45 -06:00

10 KiB

👁️ VISTA PREVIA EN TIEMPO REAL

Estructura HTML del Preview

<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>

            <!-- IMPORTANTE: Usar las MISMAS clases que el componente real -->
            <div id="componentPreview" class="[clases-del-componente-real]">
                <!-- HTML IDÉNTICO al del 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>

Características clave:

  • Border-left ORANGE (#FF8600) - NO navy
  • Clases IDÉNTICAS al componente del front-end
  • HTML IDÉNTICO al front-end
  • Botones Desktop/Mobile para cambiar el ancho

Reglas Críticas para Vista Previa

LO QUE NO DEBES HACER

1. NO usar inline styles que sobreescriban el CSS real

<!-- ❌ MAL: Inline styles que sobreescriben el CSS real -->
<div id="preview" class="component" style="padding: 10px; color: blue;">
    <!-- Esto NO se verá igual al front-end -->
</div>

2. NO crear CSS específico para el preview que no existe en el front-end

/* ❌ MAL: CSS específico para el preview que no existe en el front-end */
#componentPreview {
    padding: 20px;
    font-size: 16px;
    background-color: #f0f0f0;
}

3. NO modificar la estructura HTML del componente

<!-- ❌ MAL: HTML diferente al front-end -->
<div id="preview" class="my-custom-wrapper">
    <div class="component">
        <!-- Estructura diferente -->
    </div>
</div>

LO QUE DEBES HACER

1. Usar EXACTAMENTE las mismas clases que el front-end

<!-- ✅ BIEN: Usar EXACTAMENTE las mismas clases que el front-end -->
<div id="topBarPreview" class="top-notification-bar">
    <div class="container">
        <div class="notification-content">
            <!-- Estructura IDÉNTICA al front-end -->
        </div>
    </div>
</div>

2. Cargar el CSS del front-end en el admin

<!-- ✅ BIEN: Cargar el CSS real del front-end -->
<link rel="stylesheet" href="../../Css/style.css">

3. Solo aplicar estilos si es ABSOLUTAMENTE necesario con !important

/* ✅ BIEN: Solo si el CSS del front-end no se aplica correctamente */
#componentPreview.top-notification-bar {
    /* Solo agregar si es necesario para el contexto del admin */
    border: 1px solid #e9ecef; /* Border para debugging visual */
}

Ejemplo Completo: Top Bar Preview

HTML del Front-end (Original)

<div class="top-notification-bar">
    <div class="container">
        <div class="notification-content">
            <i class="bi bi-megaphone-fill notification-icon"></i>
            <span class="notification-text">
                <strong class="notification-highlight">Nuevo:</strong>
                Accede a más de 200,000 APUs actualizados.
            </span>
            <a href="/catalogo" class="notification-link">
                Ver Catálogo →
            </a>
        </div>
    </div>
</div>

HTML del Preview (Admin) CORRECTO

<!-- ✅ IDÉNTICO al front-end -->
<div id="topBarPreview" class="top-notification-bar">
    <div class="container">
        <div class="notification-content">
            <i class="bi bi-megaphone-fill notification-icon" id="previewIcon"></i>
            <span class="notification-text">
                <strong class="notification-highlight" id="previewHighlight">Nuevo:</strong>
                <span id="previewMessage">Accede a más de 200,000 APUs actualizados.</span>
            </span>
            <a href="/catalogo" class="notification-link" id="previewLink">
                Ver Catálogo →
            </a>
        </div>
    </div>
</div>

Diferencias permitidas:

  • IDs agregados para manipulación con JavaScript (id="previewIcon", id="previewMessage", etc.)
  • Clases CSS IDÉNTICAS al front-end
  • Estructura HTML IDÉNTICA

CSS para Vista Previa

Principio: NO sobreescribir estilos del front-end

/* REGLA DE ORO: NO sobreescribir estilos del front-end */
/* Solo agregar si es absolutamente necesario */

/* ✅ Permitido: Border para distinguir visualmente el preview en el admin */
#topBarPreview {
    border: 1px solid #e9ecef;
    border-radius: 0.375rem;
}

/* ❌ NO permitido: Sobreescribir propiedades del componente */
#topBarPreview {
    padding: 20px !important;  /* ❌ Esto hará que no se vea igual */
    font-size: 18px !important; /* ❌ Esto hará que no se vea igual */
}

JavaScript para updatePreview()

Patrón Básico

/**
 * Actualiza la vista previa en tiempo real
 */
function updatePreview() {
    const preview = document.getElementById('topBarPreview');
    if (!preview) return;

    // REGLA: Solo modificar propiedades que el usuario puede cambiar
    // NO modificar padding, margins, o estructura del HTML

    // 1. Actualizar colores
    const bgColor = document.getElementById('bgColor').value;
    const textColor = document.getElementById('textColor').value;
    preview.style.backgroundColor = bgColor;
    preview.style.color = textColor;

    // 2. Actualizar texto
    const highlightText = document.getElementById('highlightText').value;
    const messageText = document.getElementById('messageText').value;
    document.getElementById('previewHighlight').textContent = highlightText;
    document.getElementById('previewMessage').textContent = messageText;

    // 3. Actualizar link
    const showLink = document.getElementById('showLink').checked;
    const linkElement = document.getElementById('previewLink');
    linkElement.style.display = showLink ? 'inline-block' : 'none';

    if (showLink) {
        const linkText = document.getElementById('linkText').value;
        const linkUrl = document.getElementById('linkUrl').value;
        const linkTarget = document.getElementById('linkTarget').value;
        linkElement.textContent = linkText;
        linkElement.href = linkUrl;
        linkElement.target = linkTarget;
    }

    // 4. Mostrar/ocultar icono
    const showIcon = document.getElementById('showIcon').checked;
    const iconElement = document.getElementById('previewIcon');
    iconElement.style.display = showIcon ? 'inline-block' : 'none';

    // 5. Cambiar clase del icono
    const iconClass = document.getElementById('iconClass').value;
    iconElement.className = iconClass + ' notification-icon';
}

Conectar updatePreview() a Todos los Campos

function initializeEventListeners() {
    // Lista de campos que deben actualizar el preview
    const fields = [
        'bgColor',
        'textColor',
        'highlightColor',
        'highlightText',
        'messageText',
        'showLink',
        'linkText',
        'linkUrl',
        'linkTarget',
        'showIcon',
        'iconClass',
        'fontSize'
    ];

    // Conectar event listeners
    fields.forEach(fieldId => {
        const element = document.getElementById(fieldId);
        if (element) {
            if (element.type === 'checkbox') {
                element.addEventListener('change', updatePreview);
            } else {
                element.addEventListener('input', updatePreview);
            }
        }
    });
}

Botones Desktop/Mobile

HTML

<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>

JavaScript

const btnDesktop = document.getElementById('previewDesktop');
const btnMobile = document.getElementById('previewMobile');
const preview = document.getElementById('topBarPreview');

btnDesktop.addEventListener('click', function() {
    // Activar botón
    this.classList.add('active');
    btnMobile.classList.remove('active');

    // Cambiar ancho del preview
    preview.style.maxWidth = '100%';
    preview.style.margin = '0';
});

btnMobile.addEventListener('click', function() {
    // Activar botón
    this.classList.add('active');
    btnDesktop.classList.remove('active');

    // Cambiar ancho del preview (simular mobile)
    preview.style.maxWidth = '375px';
    preview.style.margin = '0 auto';
});

Checklist de Vista Previa

Antes de considerar completa la vista previa, verificar:

  • HTML del preview es IDÉNTICO al front-end
  • Se usan las MISMAS clases CSS que el componente real
  • Se carga el archivo CSS del front-end (../../Css/style.css)
  • NO hay inline styles que sobreescriban propiedades del componente
  • La función updatePreview() está conectada a todos los campos
  • Los botones Desktop/Mobile funcionan correctamente
  • El preview se ve IDÉNTICO al componente en el sitio real

Debugging de Vista Previa

Problema: El preview no se ve igual al front-end

Solución:

  1. Abrir DevTools (F12)
  2. Inspeccionar el elemento del preview
  3. Verificar que se cargan los estilos correctos:
Computed Styles →
    padding: 0.5rem 0 (debe venir de style.css)
    background-color: rgb(14, 35, 55) (debe venir del inline style del preview)
  1. Si hay estilos incorrectos:
    • Verificar que style.css esté cargado
    • Verificar que las clases CSS sean idénticas
    • Verificar que no haya inline styles conflictivos

Volver al Índice

← Volver al README