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

@jbernous/cts-ui

v0.7.0

Published

CTS-UI — Librería transversal de componentes UI reutilizables

Readme

CTS-UI

Libreria transversal de componentes UI reutilizables de CoTessIA.

Proposito del producto: tomar componentes de librerias y registries de referencia (shadcn Base UI, ReUI, Base UI) y convertirlos en piezas propias, hermosas y funcionales, listas para reutilizar en los desarrollos posteriores. La definicion completa (que es una pieza terminada, principios e invariantes, fuentes de referencia y barra estetica) vive en docs/producto.md.

Stack

  • React 19
  • TypeScript 6
  • Vite 8
  • Tailwind CSS 4
  • Recharts 3
  • @base-ui/react

Estructura

src/
  primitives/   Componentes base (Button, Card, Input, Dialog, etc.)
  charts/       Graficas (Area, Bar, Pie, Radar, Radial)
  kpi/          Tarjetas KPI y utilidades
  shell/        Shell de aplicacion (Sidebar, Header, AppShell)
  patterns/     Patrones compuestos (KpiGrid, Pagination)
  tokens/       Design tokens, utilidades (cn, status, density)
  ui-lab/       Catalogo y sistema de curaduria

Imágenes del demo (src/patterns/storefront.demo-images.ts): el patrón de demo del storefront usa URLs reales de la tienda de referencia para verse con fotos en vez de los placeholders SVG. Es material de terceros y de referencia para evaluar el diseño: no es un activo del proyecto, no se redistribuye (solo se apunta al CDN de la tienda) y sus URLs están versionadas por producto (?v=…), así que pueden morir cuando cambien una campaña. El archivo se puede borrar entero: todos los call sites pasan por productImage(fill, size, remoteUrl?), que ante undefined vuelve al placeholder neutro, sin tocar ninguna pieza del subset. Las categorías del demo tienen id propios, así que su mapeo es una aproximación declarada (ver la cabecera del archivo).

Desarrollo

npm install
npm run dev        # Dev server del Lab en http://localhost:5273
npm run build      # Library build
npm run typecheck  # TypeScript check

Empaquetado (tarball)

npm pack --dry-run --ignore-scripts --json   # inspeccionar el packlist

prepack corre npm run build: npm pack sobre un clon limpio no tiene dist/ (está gitignored) y el tarball nunca debe salir sin bundles frescos. Por eso cualquier npm pack dispara un build completo; para mirar sólo la lista de archivos, usar --ignore-scripts como arriba.

files acota el tarball a lo que exports declara: los artefactos del dev-app (dist/ui-lab/**, dist/App.d.ts, dist/main.d.ts y sus .map) no se publican. El contrato está cubierto por src/packaging.test.ts, que no necesita build ni invoca npm (se saltea si dist/ no existe).

Guardarraíl e2e (Playwright)

npm run test:e2e   # Playwright contra el Lab (levanta Vite en el puerto 5273)

Corre las invariantes de navegador que jsdom no puede ver (geometría real del Frame, alternancia Plus/Minus y contraste de iconos) sobre el Lab en http://localhost:5273 — no en 5173, que en esta máquina sirve otra app.

El config usa channel: "chrome": necesita el Chrome del sistema y NO descarga navegadores (npx playwright install no hace falta). Si la máquina no tiene Chrome, el fallback es npx playwright install chromium y cambiar channel a "chromium" en playwright.config.ts.

npm run test:e2e queda fuera de npm test a propósito: la suite jsdom (Vitest) no debe depender de un navegador.

Uso

import { Button } from "@jbernous/cts-ui"
import "@jbernous/cts-ui/styles.css"

@jbernous/cts-ui/styles.css es obligatorio, una sola vez, para @jbernous/cts-ui y @jbernous/cts-ui/auth (el CSS completo del sistema). Medido: dist/auth.js tiene 0 referencias a .css y dist/index.css cubre el 100% de las clases que usa auth. Sin ese import las pantallas renderizan sin estilos.

Subpath @jbernous/cts-ui/auth (pantallas de login/signup, UI pura):

import { LoginScreen } from "@jbernous/cts-ui/auth"
import "@jbernous/cts-ui/styles.css"

Subset @jbernous/cts-ui/store — su propio CSS acotado

import "@jbernous/cts-ui/store/styles.css"   // ANTES del CSS propio
import { StorePrice } from "@jbernous/cts-ui/store"

@jbernous/cts-ui/store/styles.css (dist/store.css) trae sólo las utilidades del subset: 15,9 kB (3,7 kB gzip) frente a 85,6 kB del completo, sin preflight y sin los resets globales que le repintan el body al consumidor. Es plano (sin @layer) a propósito, y la razón está medida:

  • Tailwind 3 secuestra @layer base|components|utilities en su plugin PostCSS y rechaza el stylesheet entero (@layer utilities is used but no matching @tailwind utilities directive is present) — un consumidor Tailwind 3 no podría ni importarlo;
  • y el estilo sin capa le gana al estilo con capa sin importar especificidad, así que un reset de tipo del consumidor (h1,h2,… { font-size: inherit; font-weight: inherit }) le comía la tipografía al componente (medido: <h1> en 400 con capas, 700 plano).

En Tailwind 3, importalo antes de tu propio CSS. Con artefacto plano el orden decide los empates clase-vs-clase: el que manda en su documento es el consumidor, así que va primero la librería.

En Tailwind 4, metelo en una capa propia. Un CSS plano le gana a todo lo que esté en capa, sin importar orden ni especificidad — y Tailwind 4 emite todo en capas. Importado tal cual, las utilidades de la librería pisarían a las del consumidor y no habría forma de ordenarlas. La solución es una línea:

@layer theme, base, components, cts, utilities;   /* orden explícito, cts antes de utilities */
@import "tailwindcss";
@import "@jbernous/cts-ui/store/styles.css" layer(cts);

Así cts queda por debajo de utilities y el consumidor gana los empates. Un solo artefacto sirve a los dos mundos: plano para Tailwind 3, en capa propia para Tailwind 4. Verificado en smoke/ (Next 15 + Tailwind 4) con la aserción la capa \cts` queda antes de `utilities``.

Sección @jbernous/cts-ui/store-columbia — subpath propio, con su CSS

import "@jbernous/cts-ui/store-columbia/styles.css"   // ANTES del CSS propio
import { ColumbiaHeader } from "@jbernous/cts-ui/store-columbia"

Son las nueve piezas del relevamiento Columbia Chile (barra de anuncios, header, hero, carrito, consentimiento de cookies, chat, volver arriba, badge tecnológico y slider de colección). Viaja como subpath propio y no dentro de ./store porque Columbia es la procedencia de las piezas, no un dominio del design system: un consumidor que no arma ese storefront no carga estas nueve.

@jbernous/cts-ui/store-columbia/styles.css (dist/store-columbia.css) es el mismo tipo de artefacto que el del subset —plano, sin preflight, con las clases de colapso propias cts-layout-col-* de la sección— y se consume igual: Tailwind 3, antes de tu propio CSS; Tailwind 4, en capa propia (@import "@jbernous/cts-ui/store-columbia/styles.css" layer(cts), con el mismo @layer theme, base, components, cts, utilities de arriba).

Un solo import alcanza. El artefacto cubre el directorio de la sección y también las tres piezas del subset que la sección compone (ColumbiaHeader monta StoreThemeToggle; ColumbiaCartDrawer monta StoreCartItem y StorePrice): sus clases viajan acá dentro, así que un consumidor de la sección importa un stylesheet y no necesita además @jbernous/cts-ui/store/styles.css. Lo que no cubre es el resto de src/store/**: el escaneo nombra esas tres piezas archivo por archivo, nunca el subset entero. Si además usás piezas sueltas del subset, sí te toca el artefacto del subset (los dos, antes del CSS propio). El detalle medido está en docs/ecommerce/build-subpaths.md §4.3.

Los tipos resuelven desde dist/auth/index.d.ts, dist/store/index.d.ts y dist/store-columbia/index.d.ts (el exports de cada subpath ordena types primero). Los detalles de empaquetado (exports, sideEffects, tsconfig.build.json, medición del bundle y el análisis diferido de exports por pieza) viven en docs/ecommerce/build-y-tipos.md; el porqué de un config de Vite por artefacto y el layout de subpaths, en docs/ecommerce/build-subpaths.md.

Requisitos del consumidor

  • React 19 (peerDependencies.react = ^19.0.0): un proyecto en React 18 no instala sin conflicto.
  • Bundler: los artefactos son ESM + CJS; no hay UMD desde 67b2f3b.
  • moduleResolution: bundler (o node16/nodenext). El viejo "node" no lee exports y no resuelve @jbernous/cts-ui/store, @jbernous/cts-ui/auth ni @jbernous/cts-ui/store-columbia (TS2307: Cannot find module).
  • Next / App Router: envolvé el componente en un client boundary ("use client"). Los subpaths no traen la directiva y las primitivas que componen (Button, vía @base-ui/react) usan hooks.
  • Tailwind 3: importá el artefacto del subpath que uses — @jbernous/cts-ui/store/styles.css y/o @jbernous/cts-ui/store-columbia/styles.css (la sección trae el suyo, uno solo, y cubre las piezas del subset que compone) — como módulo, antes del CSS propio. El stylesheet completo @jbernous/cts-ui/styles.css no se puede importar por bundler en un consumidor Tailwind 3: su plugin PostCSS rechaza cualquier @layer utilities que venga de afuera. Alternativa para ese caso: servirlo como asset estático con <link>.
  • Tailwind 4: los mismos archivos, pero en capa propia — @import "…/store/styles.css" layer(cts) o …/store-columbia/styles.css layer(cts) — y con el orden de capas declarado (ver arriba). El paquete no los envuelve por vos: la capa es una decisión del consumidor.

Licencia

MIT