feat: agregar design system completo con 2 temas (Industrial + Moderno)
- Tokens CSS con variables para ambos temas (dark/light) - 21 componentes reutilizables (buttons, cards, tables, modals, etc.) - 10 pantallas POS (login, catálogo, POS, inventario, clientes, facturación, contabilidad, dashboard, configuración, reportes) - Preview interactivo con selector de tema - Generado por el equipo de Hugo (Milo-UX, Iris-UI, Zara-Frontend)
This commit is contained in:
453
docs/design/design-system/components/tables.html
Normal file
453
docs/design/design-system/components/tables.html
Normal file
@@ -0,0 +1,453 @@
|
||||
<!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 — Tables</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: var(--z-sticky);
|
||||
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);
|
||||
}
|
||||
.label-text {
|
||||
font-size: var(--text-caption); color: var(--color-text-muted);
|
||||
text-transform: uppercase; letter-spacing: var(--tracking-widest);
|
||||
font-weight: var(--font-weight-semibold); margin-bottom: var(--space-3);
|
||||
}
|
||||
|
||||
/* ====== Table Container ====== */
|
||||
.table-container {
|
||||
background: var(--color-bg-elevated);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
overflow: hidden;
|
||||
}
|
||||
[data-theme="industrial"] .table-container {
|
||||
border-radius: 0;
|
||||
clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
|
||||
}
|
||||
|
||||
/* Table Toolbar */
|
||||
.table-toolbar {
|
||||
display: flex; align-items: center; gap: var(--space-3);
|
||||
padding: var(--space-4) var(--space-5);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.table-toolbar .search-input {
|
||||
flex: 1; min-width: 200px;
|
||||
padding: var(--space-2) var(--space-4);
|
||||
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);
|
||||
outline: none; transition: var(--transition-fast);
|
||||
}
|
||||
.table-toolbar .search-input::placeholder { color: var(--color-text-muted); }
|
||||
.table-toolbar .search-input:focus {
|
||||
border-color: var(--color-border-focus); box-shadow: var(--shadow-focus);
|
||||
}
|
||||
.table-toolbar .toolbar-btn {
|
||||
padding: var(--space-2) var(--space-3);
|
||||
font-family: var(--font-body); font-size: var(--text-body-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
background: var(--color-bg-base); color: var(--color-text-secondary);
|
||||
border: 1px solid var(--color-border); border-radius: var(--radius-md);
|
||||
cursor: pointer; transition: var(--transition-fast);
|
||||
display: flex; align-items: center; gap: var(--space-1);
|
||||
}
|
||||
.table-toolbar .toolbar-btn:hover {
|
||||
background: var(--color-primary-muted); color: var(--color-primary);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
/* Table Itself */
|
||||
.table {
|
||||
width: 100%; border-collapse: collapse;
|
||||
}
|
||||
.table thead th {
|
||||
padding: var(--space-3) var(--space-4);
|
||||
text-align: left;
|
||||
font-size: var(--text-caption);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: var(--tracking-wider);
|
||||
background: var(--color-surface-1);
|
||||
border-bottom: 2px solid var(--color-border);
|
||||
cursor: pointer; user-select: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.table thead th:hover {
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
.table thead th .sort-icon {
|
||||
display: inline-block; margin-left: var(--space-1);
|
||||
opacity: 0.3; font-size: 10px;
|
||||
}
|
||||
.table thead th.sorted .sort-icon { opacity: 1; color: var(--color-primary); }
|
||||
|
||||
.table tbody tr {
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
transition: var(--transition-fast);
|
||||
}
|
||||
.table tbody tr:hover {
|
||||
background: var(--color-primary-muted);
|
||||
}
|
||||
.table tbody tr:last-child { border-bottom: none; }
|
||||
|
||||
.table tbody td {
|
||||
padding: var(--space-3) var(--space-4);
|
||||
font-size: var(--text-body-sm);
|
||||
vertical-align: middle;
|
||||
}
|
||||
.table tbody td.mono {
|
||||
font-family: var(--font-mono);
|
||||
letter-spacing: var(--tracking-wide);
|
||||
}
|
||||
|
||||
/* Cell Variants */
|
||||
.badge {
|
||||
display: inline-block; padding: 2px var(--space-2);
|
||||
font-size: 11px; font-weight: var(--font-weight-semibold);
|
||||
border-radius: var(--radius-sm); text-transform: uppercase;
|
||||
letter-spacing: var(--tracking-wider);
|
||||
}
|
||||
.badge-success { background: var(--color-success-light); color: var(--color-success-dark); }
|
||||
.badge-warning { background: var(--color-warning-light); color: var(--color-warning-dark); }
|
||||
.badge-error { background: var(--color-error-light); color: var(--color-error-dark); }
|
||||
.badge-neutral {
|
||||
background: var(--color-surface-3); color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
[data-theme="industrial"] .badge-success { background: rgba(34,197,94,0.15); color: var(--color-success); }
|
||||
[data-theme="industrial"] .badge-warning { background: rgba(234,179,8,0.15); color: var(--color-warning); }
|
||||
[data-theme="industrial"] .badge-error { background: rgba(239,68,68,0.15); color: var(--color-error); }
|
||||
[data-theme="industrial"] .badge-neutral { background: var(--color-surface-3); color: var(--color-text-muted); }
|
||||
|
||||
.action-btn {
|
||||
padding: var(--space-1) var(--space-2);
|
||||
background: none; border: 1px solid var(--color-border);
|
||||
color: var(--color-text-muted); border-radius: var(--radius-sm);
|
||||
cursor: pointer; font-size: 13px; transition: var(--transition-fast);
|
||||
}
|
||||
.action-btn:hover {
|
||||
color: var(--color-primary); border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
/* Checkbox in table */
|
||||
.table-checkbox {
|
||||
appearance: none; width: 18px; height: 18px;
|
||||
border: 2px solid var(--color-border-strong);
|
||||
border-radius: 3px; background: var(--color-bg-base);
|
||||
cursor: pointer; transition: var(--transition-fast);
|
||||
vertical-align: middle;
|
||||
}
|
||||
.table-checkbox:checked {
|
||||
background: var(--color-primary); border-color: var(--color-primary);
|
||||
}
|
||||
.table-checkbox:checked::after {
|
||||
content: '\2713'; color: var(--color-text-inverse);
|
||||
font-size: 12px; font-weight: bold;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
|
||||
/* ====== Pagination ====== */
|
||||
.table-pagination {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: var(--space-3) var(--space-5);
|
||||
border-top: 1px solid var(--color-border);
|
||||
flex-wrap: wrap; gap: var(--space-3);
|
||||
}
|
||||
.pagination-info {
|
||||
font-size: var(--text-body-sm); color: var(--color-text-muted);
|
||||
}
|
||||
.pagination-controls {
|
||||
display: flex; align-items: center; gap: var(--space-1);
|
||||
}
|
||||
.page-btn {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
width: 36px; height: 36px;
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-bg-base); color: var(--color-text-secondary);
|
||||
border-radius: var(--radius-md); cursor: pointer;
|
||||
font-family: var(--font-body); font-size: var(--text-body-sm);
|
||||
transition: var(--transition-fast);
|
||||
}
|
||||
.page-btn:hover:not(:disabled) {
|
||||
background: var(--color-primary-muted); color: var(--color-primary);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
.page-btn.active {
|
||||
background: var(--color-primary); color: var(--color-text-inverse);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
.page-btn:disabled { opacity: 0.3; cursor: not-allowed; }
|
||||
|
||||
.per-page-select {
|
||||
padding: var(--space-1) var(--space-2);
|
||||
font-family: var(--font-body); font-size: var(--text-body-sm);
|
||||
background: var(--color-bg-base); color: var(--color-text-primary);
|
||||
border: 1px solid var(--color-border); border-radius: var(--radius-md);
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="theme-switcher">
|
||||
<button class="active" onclick="setTheme('industrial')">Industrial Robusto</button>
|
||||
<button onclick="setTheme('modern')">Tecnico Moderno</button>
|
||||
</div>
|
||||
|
||||
<h1>Tables</h1>
|
||||
<p class="subtitle">Tablas con sorting, paginacion y acciones para inventario, ventas y clientes.</p>
|
||||
|
||||
<!-- Inventory Table -->
|
||||
<section>
|
||||
<h2>Tabla de Inventario</h2>
|
||||
<p class="label-text">Tabla principal con busqueda, filtros, sorting y paginacion</p>
|
||||
|
||||
<div class="table-container">
|
||||
<div class="table-toolbar">
|
||||
<input class="search-input" type="text" placeholder="Buscar producto, SKU, marca...">
|
||||
<button class="toolbar-btn">▼ Categoria</button>
|
||||
<button class="toolbar-btn">▼ Stock</button>
|
||||
<button class="toolbar-btn">📥 Exportar</button>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;"><input class="table-checkbox" type="checkbox"></th>
|
||||
<th>SKU <span class="sort-icon">▲</span></th>
|
||||
<th class="sorted">Producto <span class="sort-icon">▲</span></th>
|
||||
<th>Categoria</th>
|
||||
<th>Precio <span class="sort-icon">▼</span></th>
|
||||
<th>Stock <span class="sort-icon">▲</span></th>
|
||||
<th>Estado</th>
|
||||
<th style="width: 100px;">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><input class="table-checkbox" type="checkbox"></td>
|
||||
<td class="mono">BRM-BLT-P68064N</td>
|
||||
<td>Balatas Ceramicas Brembo</td>
|
||||
<td>Frenos</td>
|
||||
<td class="mono">$892.00</td>
|
||||
<td class="mono">24</td>
|
||||
<td><span class="badge badge-success">En stock</span></td>
|
||||
<td>
|
||||
<button class="action-btn" title="Editar">✎</button>
|
||||
<button class="action-btn" title="Eliminar">✕</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="table-checkbox" type="checkbox" checked></td>
|
||||
<td class="mono">MOB-OIL-5W30-1L</td>
|
||||
<td>Aceite Sintetico Mobil 1 5W-30</td>
|
||||
<td>Motor</td>
|
||||
<td class="mono">$345.00</td>
|
||||
<td class="mono" style="color: var(--color-warning);">3</td>
|
||||
<td><span class="badge badge-warning">Stock bajo</span></td>
|
||||
<td>
|
||||
<button class="action-btn" title="Editar">✎</button>
|
||||
<button class="action-btn" title="Eliminar">✕</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="table-checkbox" type="checkbox"></td>
|
||||
<td class="mono">MNR-AMT-72321</td>
|
||||
<td>Amortiguador Monroe Sensatrac</td>
|
||||
<td>Suspension</td>
|
||||
<td class="mono">$1,650.00</td>
|
||||
<td class="mono" style="color: var(--color-error);">0</td>
|
||||
<td><span class="badge badge-error">Sin stock</span></td>
|
||||
<td>
|
||||
<button class="action-btn" title="Editar">✎</button>
|
||||
<button class="action-btn" title="Eliminar">✕</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="table-checkbox" type="checkbox"></td>
|
||||
<td class="mono">NGK-BUJ-BKR6E</td>
|
||||
<td>Bujia NGK BKR6E Iridium</td>
|
||||
<td>Encendido</td>
|
||||
<td class="mono">$189.00</td>
|
||||
<td class="mono">156</td>
|
||||
<td><span class="badge badge-success">En stock</span></td>
|
||||
<td>
|
||||
<button class="action-btn" title="Editar">✎</button>
|
||||
<button class="action-btn" title="Eliminar">✕</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="table-checkbox" type="checkbox"></td>
|
||||
<td class="mono">GTS-FLT-AF123</td>
|
||||
<td>Filtro de Aire Gates AF123</td>
|
||||
<td>Filtracion</td>
|
||||
<td class="mono">$245.00</td>
|
||||
<td class="mono">42</td>
|
||||
<td><span class="badge badge-success">En stock</span></td>
|
||||
<td>
|
||||
<button class="action-btn" title="Editar">✎</button>
|
||||
<button class="action-btn" title="Eliminar">✕</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="table-checkbox" type="checkbox"></td>
|
||||
<td class="mono">BOH-DSC-BD5678</td>
|
||||
<td>Disco de Freno Bosch BD5678</td>
|
||||
<td>Frenos</td>
|
||||
<td class="mono">$1,120.00</td>
|
||||
<td class="mono" style="color: var(--color-warning);">5</td>
|
||||
<td><span class="badge badge-warning">Stock bajo</span></td>
|
||||
<td>
|
||||
<button class="action-btn" title="Editar">✎</button>
|
||||
<button class="action-btn" title="Eliminar">✕</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="table-pagination">
|
||||
<div class="pagination-info">
|
||||
Mostrando <strong>1-6</strong> de <strong>1,423</strong> productos
|
||||
|
|
||||
<select class="per-page-select">
|
||||
<option>10 por pagina</option>
|
||||
<option>25 por pagina</option>
|
||||
<option>50 por pagina</option>
|
||||
<option>100 por pagina</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="pagination-controls">
|
||||
<button class="page-btn" disabled title="Primera">«</button>
|
||||
<button class="page-btn" disabled title="Anterior">‹</button>
|
||||
<button class="page-btn active">1</button>
|
||||
<button class="page-btn">2</button>
|
||||
<button class="page-btn">3</button>
|
||||
<button class="page-btn">...</button>
|
||||
<button class="page-btn">143</button>
|
||||
<button class="page-btn" title="Siguiente">›</button>
|
||||
<button class="page-btn" title="Ultima">»</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Sales Table (compact) -->
|
||||
<section>
|
||||
<h2>Tabla de Ventas</h2>
|
||||
<p class="label-text">Tabla compacta para historial de ventas del dia</p>
|
||||
|
||||
<div class="table-container">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Folio</th>
|
||||
<th>Hora</th>
|
||||
<th>Cliente</th>
|
||||
<th>Productos</th>
|
||||
<th>Total</th>
|
||||
<th>Pago</th>
|
||||
<th>Estado</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="mono">V-2026-0847</td>
|
||||
<td>14:32</td>
|
||||
<td>Taller El Rapido</td>
|
||||
<td>4 items</td>
|
||||
<td class="mono" style="font-weight: var(--font-weight-bold);">$3,680.00</td>
|
||||
<td>Credito</td>
|
||||
<td><span class="badge badge-success">Completada</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="mono">V-2026-0846</td>
|
||||
<td>13:15</td>
|
||||
<td>Publico General</td>
|
||||
<td>1 item</td>
|
||||
<td class="mono" style="font-weight: var(--font-weight-bold);">$892.00</td>
|
||||
<td>Efectivo</td>
|
||||
<td><span class="badge badge-success">Completada</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="mono">V-2026-0845</td>
|
||||
<td>12:48</td>
|
||||
<td>Refacciones Alvarez</td>
|
||||
<td>12 items</td>
|
||||
<td class="mono" style="font-weight: var(--font-weight-bold);">$15,420.00</td>
|
||||
<td>Transferencia</td>
|
||||
<td><span class="badge badge-warning">Pendiente</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="mono">V-2026-0844</td>
|
||||
<td>11:20</td>
|
||||
<td>Auto Servicio Lopez</td>
|
||||
<td>3 items</td>
|
||||
<td class="mono" style="font-weight: var(--font-weight-bold);">$2,145.00</td>
|
||||
<td>Tarjeta</td>
|
||||
<td><span class="badge badge-error">Cancelada</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
function setTheme(theme) {
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
document.querySelectorAll('.theme-switcher button').forEach(btn => {
|
||||
btn.classList.toggle('active', btn.textContent.toLowerCase().includes(theme === 'industrial' ? 'industrial' : 'tecnico'));
|
||||
});
|
||||
}
|
||||
|
||||
// Sort demo
|
||||
document.querySelectorAll('.table thead th').forEach(th => {
|
||||
th.addEventListener('click', () => {
|
||||
th.closest('thead').querySelectorAll('th').forEach(h => h.classList.remove('sorted'));
|
||||
th.classList.add('sorted');
|
||||
const icon = th.querySelector('.sort-icon');
|
||||
if (icon) {
|
||||
icon.innerHTML = icon.innerHTML === '\u25B2' ? '\u25BC' : '\u25B2';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user