Componentes V1 · Sprint P0
6 componentes nuevos del Sprint V1 (mayo 2026): cis-sidebar,
<cis-drawer>, <cis-popover>,
<cis-search>, footer variants y cis-kpi.
Filosofía Swiss × CIS — bordes finos, asimetría 5/7, mono headings,
accent variable por brand.
01·Sidebar
Side menu vertical para apps y dashboards. data-collapse="md"
colapsa labels en mobile dejando sólo iconos. Hay también data-variant="ghost"
para usarse embebido en otro container.
La sidebar se renderiza en el lado izquierdo, sticky a 100vh.
<aside class="cis-sidebar" data-collapse="md">
<div class="cis-sidebar__brand">
<a href="/"><img src="/brand/cis/mark.svg"> <span>Brand</span></a>
</div>
<nav class="cis-sidebar__nav">
<div class="cis-sidebar__section">
<h4 class="cis-sidebar__heading">Sección</h4>
<ul>
<li><a class="cis-sidebar__link" data-active>
<svg ...></svg>
<span class="cis-sidebar__label">Item activo</span>
</a></li>
</ul>
</div>
</nav>
<div class="cis-sidebar__footer">v1.0.0</div>
</aside>
Variantes
data-collapse="md"· esconde labels en <768px (default mostrado arriba).data-collapse="sm"· colapsa solo en <480px.data-collapsed· estado colapsado forzado (controlado por JS del consumer).data-variant="ghost"· sin background ni border-right; útil embebida.
02·Drawer
Panel lateral deslizable. Web component <cis-drawer> con
métodos open()/close()/toggle(). Cierra con click en overlay, click en X o ESC.
Detalle del cliente
Drawer lateral derecho · size md.
Cerrá con ESC, click en overlay o el botón X.
Filtros
Drawer izquierdo size sm.
Notificaciones
Drawer desde top.
Selector móvil
Drawer desde bottom — clásico patrón sheet móvil.
Vista expandida
Size lg = 560px.
<cis-drawer id="my-drawer" side="right" size="md">
<h2 slot="header">Título</h2>
<p>Contenido del drawer</p>
<div slot="footer">
<button class="btn">Cancelar</button>
<button class="btn btn-primary">Guardar</button>
</div>
</cis-drawer>
<script>
document.getElementById('my-drawer').open();
// Eventos: cis:drawer:open, cis:drawer:close (bubble)
</script>
Variantes
side="right|left|top|bottom"· defaultright.size="sm|md|lg|full"· 320 / 400 / 560 / 100% para laterales; 30 / 50 / 70 / 100vh para vertical.open· atributo booleano que refleja el estado.- Métodos:
.open() / .close() / .toggle()+ legacy.show() / .hide().
03·Popover
Menú flotante anclado a un trigger. Posicionamiento auto-flip si no entra. Sin librerías externas.
<cis-popover placement="bottom-start">
<button slot="trigger" class="btn">Más opciones</button>
<ul class="cis-popover__items">
<li><a class="cis-popover__item">
Editar <span class="cis-popover__shortcut">⌘E</span>
</a></li>
<hr class="cis-popover__separator">
<li><a class="cis-popover__item" data-variant="danger">Eliminar</a></li>
</ul>
</cis-popover>
Variantes
placement="bottom-start|bottom-end|top-start|top-end"· defaultbottom-start. Auto-flip si no entra.offset· pixels entre trigger y panel (default 4).data-variant="danger"en cada__itempara acciones destructivas.__shortcut· keyboard shortcut a la derecha en mono 11px.__separator· hr entre grupos.__header· label de sección uppercase mono.
04·Search
Quick search con dropdown de resultados. Atajo global ⌘K /
Ctrl+K abre el primer cis-search del documento. Soporta
data-source URL o callback programático.
Probá escribir cualquier letra. Los resultados son mock estáticos — abajo el código.
<cis-search placeholder="Buscar..." min-chars="2" show-hint></cis-search>
<script>
// Opción 1: URL JSON
// <cis-search data-source="/api/search"></cis-search>
// Opción 2: callback programático
const s = document.querySelector('cis-search');
s.search = async (q) => {
return [
{ title: 'USAIA', subtitle: 'Transcripción audio', url: '/usaia' },
{ title: 'Periodismo2', subtitle: 'API noticias', url: '/p2' },
].filter(r => r.title.toLowerCase().includes(q.toLowerCase()));
};
s.addEventListener('cis:search:select', (e) => {
console.log('selected', e.detail.result);
});
</script>
Variantes
placeholder,min-chars(default 2),data-source(URL).show-hint· muestra ⌘K a la derecha del input.- Result shape:
{ title, subtitle?, url?, icon? }. - Teclado: ↑/↓ navegar · Enter seleccionar · Esc cerrar.
- Eventos:
cis:search:select,cis:search:open,cis:search:close.
05·Footer variants
Variantes CSS de presentación para el footer. El <cis-footer>
web component sigue funcionando igual; estas clases se aplican a un footer estático
o se reciben vía [data-variant].
corporate · 4 columnas, padding amplio
product · 5/7 asimetría Swiss
app · 1 row mínimo
<footer class="cis-footer" data-variant="corporate">
<div class="cis-footer__grid">
<div class="cis-footer__col cis-footer__brand-block">...</div>
<div class="cis-footer__col">...</div>
<div class="cis-footer__col">...</div>
<div class="cis-footer__col">...</div>
</div>
<div class="cis-footer__attribution">© ...</div>
</footer>
Variantes
data-variant="corporate"· 4 cols, padding 3rem, atribución abajo. Marketing.data-variant="product"· 2 cols 5/7 asimétrico, padding 1.5rem, mini atribución mono. Apps.data-variant="app"· 1 row, font 11px mono, version badge. Dashboards densos.
06·KPI
KPI card Swiss: número grande, label uppercase mono, delta con trend, sparkline opcional. Border-top 2px solid en lugar de caja completa con sombra.
variant="bordered"
<div class="cis-kpi" data-trend="up">
<div class="cis-kpi__label">Productos activos</div>
<div class="cis-kpi__value">1.247</div>
<div class="cis-kpi__delta" data-trend="up">+12 vs. último mes</div>
<svg class="cis-kpi__sparkline" viewBox="0 0 120 30">
<polyline points="0,22 20,18 40,20 60,15 80,12 100,8 120,5"/>
</svg>
</div>
Variantes
data-trend="up|down|flat"· color del delta y arrow. En el card entero, también colorea el border-top.data-density="compact"· padding-top 0.5rem, value 1.5rem.data-variant="bordered"· agrega borde completo + bg-surface (boxed).cis-kpi-grid· grid utility conauto-fit minmax(180px, 1fr).