Files
Autoparts-DB/docs/design/design-system/components/selector-periodo.html
Lucy ccd3962458 feat(design): add 16 new components + update 5 pages (ronda 2)
Bloqueantes POS: modal-pago, ticket-termico, banner-cliente, fkeys-footer, columnas-costo-margen
Componentes nuevos: calculadora-cambio, panel-deslizante, badge-cfdi, arbol-colapsable, tarjeta-metrica, grafica-barras, selector-periodo, etiqueta-codigo-barras
Estados: estado-vacio, banner-offline, modal-confirmacion
Páginas actualizadas: facturación, contabilidad, dashboard, configuración, reportes
2026-04-01 07:06:34 +00:00

415 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="es" data-theme="industrial">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nexus Autoparts — Selector de Período</title>
<link rel="stylesheet" href="../tokens/tokens.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: var(--font-body); background: var(--color-bg-base);
color: var(--color-text-primary); padding: var(--space-8);
transition: var(--transition-normal);
}
.theme-switcher {
position: sticky; top: 0; z-index: calc(var(--z-modal) + 10);
display: flex; gap: var(--space-2);
padding: var(--space-3) var(--space-4);
background: var(--color-bg-elevated);
border-bottom: 1px solid var(--color-border);
margin: calc(-1 * var(--space-8)); margin-bottom: var(--space-8);
}
.theme-switcher button {
padding: var(--space-2) var(--space-4);
border: 1px solid var(--color-border);
background: var(--color-bg-base); color: var(--color-text-primary);
border-radius: var(--radius-md); cursor: pointer;
font-family: var(--font-body); font-size: var(--text-body-sm);
transition: var(--transition-fast);
}
.theme-switcher button.active {
background: var(--color-primary); color: var(--color-text-inverse);
border-color: var(--color-primary);
}
h1 { font-family: var(--font-heading); font-size: var(--text-h2);
font-weight: var(--heading-weight-primary); margin-bottom: var(--space-2);
color: var(--color-text-accent); }
.subtitle { color: var(--color-text-muted); font-size: var(--text-body); margin-bottom: var(--space-8); }
section { margin-bottom: var(--space-10); }
section > h2 {
font-family: var(--font-heading); font-size: var(--text-h4);
font-weight: var(--heading-weight-secondary); color: var(--color-text-secondary);
margin-bottom: var(--space-4); padding-bottom: var(--space-2);
border-bottom: 1px solid var(--color-border);
}
/* ── Shared form styles ── */
.form-label {
display: block;
font-size: var(--text-label);
font-weight: var(--font-weight-semibold);
color: var(--color-text-secondary);
margin-bottom: var(--space-1);
text-transform: uppercase;
letter-spacing: var(--tracking-wider);
}
select, input[type="date"] {
appearance: none;
-webkit-appearance: none;
font-family: var(--font-body);
font-size: var(--text-body-sm);
color: var(--color-text-primary);
background: var(--color-bg-base);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
padding: var(--space-2) var(--space-3);
padding-right: var(--space-8);
transition: var(--transition-fast);
cursor: pointer;
min-width: 0;
}
select:hover, input[type="date"]:hover {
border-color: var(--color-border-strong);
}
select:focus, input[type="date"]:focus {
outline: none;
border-color: var(--color-border-focus);
box-shadow: var(--shadow-focus);
}
input[type="date"] {
padding-right: var(--space-3);
}
/* Select arrow */
.select-wrap {
position: relative;
display: inline-block;
}
.select-wrap::after {
content: '';
position: absolute;
right: 12px; top: 50%;
transform: translateY(-50%);
width: 0; height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid var(--color-text-muted);
pointer-events: none;
}
/* ── Buttons ── */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-2);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-md);
border: 1px solid transparent;
cursor: pointer;
transition: var(--transition-fast);
white-space: nowrap;
}
.btn-primary {
background: var(--btn-primary-bg);
color: var(--btn-primary-text);
border-color: var(--btn-primary-border);
}
.btn-primary:hover { background: var(--btn-primary-bg-hover); }
.btn-primary:active { background: var(--btn-primary-bg-active); }
.btn-ghost {
background: var(--btn-ghost-bg);
color: var(--btn-ghost-text);
border-color: var(--btn-ghost-border);
}
.btn-ghost:hover {
background: var(--color-surface-2);
}
/* ── Period Selector: Dropdown variant ── */
.period-selector {
display: flex;
align-items: flex-end;
gap: var(--space-3);
flex-wrap: wrap;
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: var(--space-4) var(--space-5);
}
.period-selector .field {
display: flex;
flex-direction: column;
}
.period-selector select {
min-width: 140px;
}
/* ── Presets (quick actions) ── */
.presets {
display: flex;
gap: var(--space-2);
flex-wrap: wrap;
}
.preset-btn {
display: inline-flex;
align-items: center;
gap: var(--space-1);
font-family: var(--font-body);
font-size: var(--text-caption);
font-weight: var(--font-weight-semibold);
padding: var(--space-1) var(--space-3);
border-radius: var(--radius-full);
border: 1px solid var(--color-border);
background: var(--color-bg-base);
color: var(--color-text-secondary);
cursor: pointer;
transition: var(--transition-fast);
white-space: nowrap;
}
.preset-btn:hover {
border-color: var(--color-primary);
color: var(--color-primary);
background: var(--color-primary-muted);
}
.preset-btn.active {
background: var(--color-primary);
color: var(--color-text-inverse);
border-color: var(--color-primary);
}
/* ── Date Range variant ── */
.date-range-selector {
display: flex;
align-items: flex-end;
gap: var(--space-3);
flex-wrap: wrap;
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: var(--space-4) var(--space-5);
}
.date-range-selector .field {
display: flex;
flex-direction: column;
}
.separator {
font-size: var(--text-body);
color: var(--color-text-muted);
padding-bottom: var(--space-2);
font-weight: var(--font-weight-semibold);
}
/* ── Selected period display ── */
.selected-display {
margin-top: var(--space-3);
padding: var(--space-3) var(--space-4);
background: var(--color-primary-muted);
border-left: 3px solid var(--color-primary);
border-radius: 0 var(--radius-md) var(--radius-md) 0;
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
}
.selected-display strong {
color: var(--color-text-accent);
font-family: var(--font-mono);
}
/* ── Compact inline variant ── */
.period-inline {
display: inline-flex;
align-items: center;
gap: var(--space-2);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: var(--space-2) var(--space-3);
}
.period-inline select {
padding: var(--space-1) var(--space-2);
padding-right: var(--space-6);
font-size: var(--text-caption);
min-width: 100px;
}
.period-inline .btn {
padding: var(--space-1) var(--space-3);
font-size: var(--text-caption);
}
.period-inline .select-wrap::after {
right: 8px;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="document.documentElement.dataset.theme='industrial'; this.classList.add('active'); this.nextElementSibling.classList.remove('active')">🔧 Industrial</button>
<button onclick="document.documentElement.dataset.theme='modern'; this.classList.add('active'); this.previousElementSibling.classList.remove('active')">⚡ Moderno</button>
</div>
<h1>Selector de Período</h1>
<p class="subtitle">Controles para seleccionar períodos de reporte: mes/año, presets rápidos y rango de fechas.</p>
<!-- ── Variant A: Dropdowns + button ── -->
<section>
<h2>Selector por Mes y Año</h2>
<div class="period-selector">
<div class="field">
<label class="form-label" for="selYear">Año</label>
<div class="select-wrap">
<select id="selYear">
<option value="2024">2024</option>
<option value="2025">2025</option>
<option value="2026" selected>2026</option>
</select>
</div>
</div>
<div class="field">
<label class="form-label" for="selMonth">Mes</label>
<div class="select-wrap">
<select id="selMonth">
<option value="1">Enero</option>
<option value="2">Febrero</option>
<option value="3">Marzo</option>
<option value="4" selected>Abril</option>
<option value="5">Mayo</option>
<option value="6">Junio</option>
<option value="7">Julio</option>
<option value="8">Agosto</option>
<option value="9">Septiembre</option>
<option value="10">Octubre</option>
<option value="11">Noviembre</option>
<option value="12">Diciembre</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="consultarPeriodo()">Consultar</button>
</div>
<div class="selected-display" id="displayPeriod">
Período seleccionado: <strong>Abril 2026</strong>
</div>
</section>
<!-- ── Variant B: Quick presets ── -->
<section>
<h2>Presets Rápidos</h2>
<div class="period-selector" style="flex-direction: column; align-items: flex-start; gap: var(--space-3);">
<div class="presets" id="presetGroup">
<button class="preset-btn active" onclick="selectPreset(this, 'Este mes')">Este mes</button>
<button class="preset-btn" onclick="selectPreset(this, 'Mes anterior')">Mes anterior</button>
<button class="preset-btn" onclick="selectPreset(this, 'Este trimestre')">Este trimestre</button>
<button class="preset-btn" onclick="selectPreset(this, 'Este año')">Este año</button>
</div>
<div class="selected-display" id="displayPreset">
Período: <strong>Abril 2026</strong> (Este mes)
</div>
</div>
</section>
<!-- ── Variant C: Date range ── -->
<section>
<h2>Rango de Fechas</h2>
<div class="date-range-selector">
<div class="field">
<label class="form-label" for="dateFrom">Desde</label>
<input type="date" id="dateFrom" value="2026-04-01">
</div>
<span class="separator"></span>
<div class="field">
<label class="form-label" for="dateTo">Hasta</label>
<input type="date" id="dateTo" value="2026-04-30">
</div>
<button class="btn btn-primary" onclick="consultarRango()">Consultar</button>
<button class="btn btn-ghost" onclick="limpiarRango()">Limpiar</button>
</div>
<div class="selected-display" id="displayRange">
Rango: <strong>01/04/2026</strong><strong>30/04/2026</strong> (30 días)
</div>
</section>
<!-- ── Variant D: Compact inline ── -->
<section>
<h2>Variante Compacta (Inline)</h2>
<p style="color: var(--color-text-muted); font-size: var(--text-body-sm); margin-bottom: var(--space-3);">
Para uso en headers de tablas o secciones con espacio reducido.
</p>
<div class="period-inline">
<div class="select-wrap">
<select>
<option>Abril</option>
<option>Marzo</option>
<option>Febrero</option>
</select>
</div>
<div class="select-wrap">
<select>
<option>2026</option>
<option>2025</option>
<option>2024</option>
</select>
</div>
<button class="btn btn-primary">Ir</button>
</div>
</section>
<script>
const meses = ['Enero','Febrero','Marzo','Abril','Mayo','Junio',
'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];
function consultarPeriodo() {
const year = document.getElementById('selYear').value;
const monthIdx = document.getElementById('selMonth').value;
const monthName = meses[monthIdx - 1];
document.getElementById('displayPeriod').innerHTML =
'Período seleccionado: <strong>' + monthName + ' ' + year + '</strong>';
}
function selectPreset(btn, label) {
document.querySelectorAll('#presetGroup .preset-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const now = new Date(2026, 3, 1); // April 2026
let text = '';
switch (label) {
case 'Este mes':
text = 'Período: <strong>Abril 2026</strong> (Este mes)';
break;
case 'Mes anterior':
text = 'Período: <strong>Marzo 2026</strong> (Mes anterior)';
break;
case 'Este trimestre':
text = 'Período: <strong>Enero — Marzo 2026</strong> (Q1 2026)';
break;
case 'Este año':
text = 'Período: <strong>Enero — Diciembre 2026</strong> (Año completo)';
break;
}
document.getElementById('displayPreset').innerHTML = text;
}
function consultarRango() {
const from = document.getElementById('dateFrom').value;
const to = document.getElementById('dateTo').value;
if (!from || !to) return;
const d1 = new Date(from), d2 = new Date(to);
const days = Math.round((d2 - d1) / (1000 * 60 * 60 * 24)) + 1;
const fmt = d => d.toLocaleDateString('es-MX', { day: '2-digit', month: '2-digit', year: 'numeric' });
document.getElementById('displayRange').innerHTML =
'Rango: <strong>' + fmt(d1) + '</strong> — <strong>' + fmt(d2) + '</strong> (' + days + ' días)';
}
function limpiarRango() {
document.getElementById('dateFrom').value = '';
document.getElementById('dateTo').value = '';
document.getElementById('displayRange').innerHTML =
'Rango: <strong>—</strong>';
}
</script>
</body>
</html>