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

@zeroq-utils/components

v1.3.7

Published

> TODO: description

Readme

@zeroq-utils/components

Librería de componentes UI para las apps de tótem/kiosco de ZeroQ (React + Tailwind).

Uso

import { Layout, Header, Footer } from "@zeroq-utils/components";

function App() {
  return (
    <Layout
      version="1.3.7"
      totemName="Recepción Principal"
      showLogo
      btnBack={() => {}}
      btnLogout={() => {}}
    >
      {/* contenido de la pantalla */}
    </Layout>
  );
}

Layout es el wrapper recomendado: renderiza Header y Footer por vos y les pasa los props correspondientes. Header y Footer también se pueden usar sueltos si necesitás más control del layout.

Layout

| Prop | Tipo | Default | Descripción | | ------------------ | -------------------- | ------- | --------------------------------------------------------------- | | header | boolean | true | Muestra/oculta el Header. | | footer | boolean | true | Muestra/oculta el Footer. | | totemName | string | "" | Nombre/posición del tótem, se muestra en el Header. | | version | string | - | Versión de la app, se muestra en el Footer como v{version}. | | showLogo | boolean | false | Muestra el logo de ZeroQ debajo de la versión en el Footer. | | accessibility | AccessibilityProps | - | Estado y handlers del panel de accesibilidad (ver abajo). | | btnBack | () => void | - | Si se pasa, el Footer muestra el botón de volver. | | btnLogout | () => void | - | Callback al confirmar el logout en el modal del Footer. | | className | string | - | Clases para el contenedor raíz. | | contentClassName | string | - | Clases para el contenedor de children. |

type AccessibilityProps = {
  value: boolean;
  setHandler: (value: boolean) => void;
  darkMode?: () => void;
  fontSize?: {
    onIncrease: () => void;
    onDecrease: () => void;
  };
};

Header

| Prop | Tipo | Default | Descripción | | ----------- | -------- | ------- | --------------------------------------------------------------------- | | totemName | string | - | Nombre/posición del tótem. Se muestra en mayúsculas junto a un ícono. |

Hora y fecha se calculan internamente (timezone America/Santiago) y no son configurables por prop. Los tres renglones (hora, fecha, totemName) usan el mismo tamaño de texto (text-3xl) para mantener jerarquía visual pareja.

Footer

| Prop | Tipo | Default | Descripción | | --------------- | -------------------- | ------- | --------------------------------------------------------------------------------------- | | version | string | - | Se muestra como v{version}. No tiene fallback: si no se pasa, se ve vundefined. | | showLogo | boolean | false | Muestra el logo de ZeroQ debajo del texto de versión. | | accessibility | AccessibilityProps | - | Habilita el panel de accesibilidad (fuente, modo oscuro, etc). | | btnBack | () => void | - | Si se pasa, muestra el botón de volver a la izquierda. | | btnLogout | () => void | - | Callback al confirmar el logout. |

El color de fondo del Footer está hardcodeado (bg-white cuando el panel de accesibilidad está abierto, bg-gray-100 en caso contrario) y hoy no es configurable por prop ni por tailwind.config.ts.

Desarrollo local / cómo probar un cambio

Este repo no usa symlinks/workspaces entre packages/components y playground, así que para ver un cambio de la librería reflejado en el playground hay que reconstruir y copiar el dist a mano:

# 0. levantar el playground (una sola vez, queda corriendo)
cd playground && npm run dev

# 1-2. en otra terminal: entrar a components y buildear
cd packages/components
npm run build

# 3-4. copiar el build generado al node_modules del playground
cd ..
rm -rf ../playground/node_modules/@zeroq-utils/components/dist
cp -r components/dist ../playground/node_modules/@zeroq-utils/components/dist

Si el playground no refleja el cambio (Vite cachea las dependencias pre-optimizadas), limpiar el caché y reiniciar el dev server:

rm -rf playground/node_modules/.vite

Ver "Mejoras pendientes" abajo — este paso manual es un candidato claro a automatizar.

Resuelto en 1.3.7

  • ~~Footer duplicado en Layout.tsx~~: se extrajo un único objeto footerProps compartido entre las dos ramas de render, en vez de repetir el JSX de <Footer> dos veces.
  • ~~Footer sin fallback para version indefinido~~: ya no renderiza vundefined.
  • ~~DialogLogout usaba <img> en vez de SvgIcon~~: ahora usa el mismo patrón de íconos que el resto del árbol.
  • ~~Dependencias runtime mal clasificadas~~: clsx, lodash, rut.js y tailwind-merge estaban en devDependencies pese a usarse en código runtime — en una instalación limpia de un consumidor externo esto rompía en producción. Movidas a dependencies. También se sacó moment (no usado, duplicaba a moment-timezone).
  • ~~.gitignore ignoraba todos los package.json del repo~~ (package.json, ./**/package.json) y tenía una regla pnpm-workspaces.yaml con typo que no hacía nada (el archivo real es pnpm-workspace.yaml). Limpiado y deduplicado.
  • ~~tsconfig.json raíz con include/paths huérfanos~~ (src, atomic, composite, alias @utils/* a un paquete packages/utils que no existe).
  • ~~Typo KeypadFuntions.ts~~ → renombrado a KeypadFunctions.ts.
  • ~~Archivos vite.config.ts.timestamp-*.mjs versionados por error en playground/~~: eliminados y agregado el patrón al .gitignore.

Mejoras pendientes / deuda técnica

  • 0% de cobertura de tests en todo el monorepo: ni packages/components ni packages/hooks tienen un solo *.test.*, a pesar de tener vitest/vitest --coverage configurado en los scripts.
  • Peso del bundle (dist/component-library.es.js ronda 1.1MB): incluye moment-timezone completo (toda la data IANA), no declara "sideEffects": false, y no hay code-splitting. Cambiarlo requiere su propio ciclo de QA porque puede afectar el tree-shaking en las apps consumidoras.
  • ESLint en formato legado (.eslintrc) mientras las devDependencies ya traen paquetes de flat-config de ESLint 9 (@eslint/js, typescript-eslint@^7) sin usarse — falta migrar a eslint.config.js.
  • Sin CI: no hay .github/workflows ni ningún pipeline que corra build/lint/test en cada PR.
  • packages/hooks semi-abandonado: useDebounce y todo ChileanDNIFormatter están escritos pero no exportados en index.ts (solo se exporta useSample, que es un stub sin lógica real). Exportarlos amplía la superficie pública del paquete hooks, así que es una decisión aparte, no un fix silencioso.
  • playground pinneado a @zeroq-utils/components@^1.2.6 mientras la librería real ya va en 1.3.x — solo funciona hoy por el flujo manual de build+copy documentado arriba. Automatizar con workspaces reales o un script sync queda pendiente.
  • Sin Storybook stories para Header, Footer ni Layout: solo los componentes atómicos (SvgIcon, Button, etc) tienen .stories.tsx.
  • Ícono de totem (TbDeviceDesktopPin, de react-icons) sigue rompiendo la consistencia del sistema de íconos propio frente al resto, que son SVGs propios vía SvgIcon.
  • Versión en package.json raíz desincronizada: el package.json de la raíz del monorepo queda fijo en 1.0.0; la versión real de la librería vive en packages/components/package.json.