npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@c80/ui

v3.6.2

Published

Libreria de componentes Angular reutilizables del ecosistema barman (icon, table, modal, select, navigation-card, login-card, etc.). Fuente unica de UI para kyron-front, midas-front y chillbox.

Readme

UI Library (@c80/ui)

Librería de componentes de interfaz de usuario reutilizables para Angular, diseñada para acelerar el desarrollo de aplicaciones con una experiencia visual consistente y componentes listos para producción.

Componentes incluidos

c80-login-card (3.2.0)

Tarjeta de login canonica del ecosistema (extraida de kyron-front): panel sci-fi con particulas, validacion inline de email/password y estado de carga. Presentacional: emite submitted con las credenciales; la llamada de auth y la navegacion son del contenedor (que controla loading).

Props principales:

  • title: string (requerido; nombre de la app: KYRON / MIDAS)
  • subtitle: string (default 'PLEASE IDENTIFY YOURSELF.')
  • loading: boolean (deshabilita el submit y muestra spinner)
  • submitted: output<LoginSubmitEvent> ({ email, password } validados)

Theming (custom properties en el host, tripletas RGB): --c80-login-accent (default rojo 220 38 38), --c80-login-accent-soft, --c80-login-accent-deep, --c80-login-bg, --c80-login-placeholder. Ademas consume --sys-text / --sys-bg-panel / --sys-error de la app.

<c80-login-card title="KYRON" [loading]="isLoading()" (submitted)="onLogin($event)" />

c80-icon

Componente para mostrar íconos SVG personalizables, con soporte para distintos tipos, colores, tamaños y modo botón.

Props principales:

  • icon: IconType (uno de los ~115 íconos disponibles en icon.definitions.ts, ej: 'check', 'cancel', 'edit', 'delete', 'add')
  • color: 'primary' | 'secondary' | 'warn' (color del ícono)
  • size: number (escala del ícono, por defecto 1)
  • button: boolean (si es true, renderiza como botón nativo)
  • disabled: boolean (deshabilita el ícono/botón)
  • type: 'button' | 'submit' | 'reset' (tipo de botón si aplica)
  • iconClick: EventEmitter<Event> (emite evento al hacer click si es botón)

Ejemplos:

<c80-icon icon="check"></c80-icon>
<c80-icon icon="delete" color="warn" [button]="true" (iconClick)="onDelete()"></c80-icon>
<c80-icon icon="add" [size]="2"></c80-icon>

c80-table

Componente de tabla dinámica con dos modos compatibles: renderizado estándar con CRUD, selección y paginación, o composición mediante templates para tablas de dominio con contenido interactivo.

Props principales:

  • data$: Observable<T[]> (fuente reactiva histórica)
  • rows: readonly T[] (fuente directa, ideal para signals y valores calculados)
  • columns: TableColDef[]
  • headerTemplate, cellTemplate, rowTemplate: templates opcionales para personalizar cabeceras, celdas o filas completas
  • caption, ariaLabel, emptyMessage: semántica accesible y estado vacío
  • density: 'compact' | 'comfortable'
  • variant: 'default' | 'bare'; bare delega la apariencia a tableClass
  • rowClass, cellClass: clases calculadas sin acoplar la librería al dominio consumidor
  • searchable + searchPlaceholder: barra de búsqueda interna; no filtra sola, emite (searchTerm) y el consumidor filtra
  • CustomTableAction.header: la acción va como botón en la cabecera de acciones (junto al "+" de create) y emite actionClick con fila vacía — para altas resueltas fuera de la tabla (p. ej. en un modal propio). Los nombres reservados (create/update/delete/cancel) lo ignoran

Debe proporcionarse data$ o rows. Los consumidores existentes que usan data$ mantienen el comportamiento anterior.

Definición de columna:

interface TableColDef {
  accessor: string;
  label: string;
  visible?: boolean;
  type?: 'string' | 'number' | 'integer' | 'boolean' | 'date' | 'password' | 'enum';
  headerClass?: string;
  cellClass?: string;
  width?: string;
  minWidth?: string;
  maxWidth?: string;
  stickyEnd?: boolean;
  ariaSort?: 'ascending' | 'descending' | 'none';
}

Ejemplo de uso:

<c80-table
  [data$]="users$"
  [columns]="userColumns"
  (errorEvent)="onError($event)"></c80-table>
userColumns = [
  { accessor: 'id', label: 'ID', type: 'number', visible: false },
  { accessor: 'name', label: 'Nombre', type: 'string' },
  { accessor: 'active', label: 'Activo', type: 'boolean' }
];

users$: Observable<User[]> = this.userService.getAll();

Ejemplo con signals y una fila de dominio:

<c80-table
  variant="bare"
  density="comfortable"
  tableClass="orders-table"
  [rows]="orders()"
  [columns]="orderColumns"
  caption="Pedidos abiertos"
  ariaLabel="Pedidos abiertos, desplazable horizontalmente"
  emptyMessage="No hay pedidos abiertos."
  [rowTemplate]="orderRow" />

<ng-template #orderRow let-order>
  <tr [class.is-late]="order.late">
    <td>{{ order.number }}</td>
    <td>{{ order.customer }}</td>
    <td><button type="button" (click)="open(order)">Ver</button></td>
  </tr>
</ng-template>

c80-action-list

Lista de acciones con título opcional, descripción e iconos. Emite el ID de la acción al hacer click (o ejecuta la función embebida en el ActionItem).

Props principales:

  • title: string (título opcional de la sección)
  • actions: ActionItem[] (acciones a mostrar)
  • actionClick: EventEmitter<string> (emite el action string al hacer click; si action es una función, se ejecuta en lugar de emitir)

ActionItem:

interface ActionItem {
  label: string;                    // Texto principal
  description?: string;             // Texto secundario
  icon?: IconType;                  // Icono a mostrar
  action?: string | (() => void);  // ID de acción a emitir, o función a ejecutar
  isDanger?: boolean;               // Estilo de peligro
  isNavigable?: boolean;            // Estilo de enlace de navegación
}

Ejemplo de uso:

<c80-action-list
  title="Mi sección"
  [actions]="actions()"
  (actionClick)="onActionClick($event)"></c80-action-list>

c80-input-field

Campo de entrada (text | email | password | number) que mantiene la estética de c80-info-list, pensado para edición inline con consistencia visual. Maneja estados de focus/readonly y eventos de teclado.

Inputs:

  • label: string (etiqueta del campo)
  • value: model<string> (two-way binding [(value)]; el output valueChange lo genera el model)
  • placeholder: string
  • type: 'text' | 'email' | 'password' | 'number' (default 'text')
  • maxLength: number | undefined
  • readonly: boolean (default false)
  • required: boolean (default false)

Outputs:

  • valueChange: emitido por el model value en cada cambio (string)
  • enterPressed: void (emite al presionar Enter)
<c80-input-field
  label="Nombre"
  [(value)]="name"
  (enterPressed)="onSubmit()"></c80-input-field>

Instalación y uso

Esta librería está pensada para usarse dentro del monorepo Nx. Importa los componentes directamente desde el punto de entrada público:

import { C80IconComponent, C80TableComponent } from '@c80/ui';

Estructura del proyecto

  • src/lib/<componente>/: un directorio por componente (icon, table, action-list, input-field, etc.)
  • src/index.ts: punto de entrada público de la librería

Desarrollo y contribución

  1. Realiza los cambios necesarios en los componentes o estilos.
  2. Ejecuta la build local:
    pnpm nx build ui
  3. Realiza un PR siguiendo las convenciones del repositorio.

Publicación en npm

Una vez publicada, la librería puede consultarse en: https://www.npmjs.com/package/@c80/ui

Contacto y soporte

Para reportar errores, solicitar funcionalidades o recibir soporte, utiliza el sistema de issues del repositorio o contacta al equipo de desarrollo.


© 2025 c80. Todos los derechos reservados.