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

@cuenti-cn/ui

v0.1.8

Published

A modern React component library built with Tailwind CSS and Radix UI

Readme

Cuenti CN UI

Una librería moderna de componentes React construida con Tailwind CSS y Radix UI.

Storybook React TypeScript Tailwind CSS

🚀 Instalación

Instalación Completa

Instala todos los componentes de una vez:

npm install cuenti-cn-ui
# o
yarn add cuenti-cn-ui
# o
pnpm add cuenti-cn-ui

Instalación por Componentes Individuales

Instala solo los componentes que necesites para un bundle más pequeño:

# Primero instala las utilidades core (siempre requeridas)
npm install @cuenti-cn/core

# Luego instala los componentes específicos que necesites
npm install @cuenti-cn/button

# O múltiples componentes a la vez
npm install @cuenti-cn/button @cuenti-cn/core

Ventajas de la instalación individual:

  • 📦 Bundle más pequeño - Solo incluye lo que necesitas
  • 🚀 Carga más rápida - Menos código para cargar
  • 🔄 Actualizaciones granulares - Actualiza solo componentes específicos

Paquetes Disponibles

| Paquete | Descripción | Instalación | Tamaño | | ------------------- | ------------------------------------------ | ------------------------------- | ------ | | cuenti-cn-ui | Paquete completo con todos los componentes | npm install cuenti-cn-ui | ~50KB | | @cuenti-cn/core | Utilidades y estilos base (requerido) | npm install @cuenti-cn/core | ~5KB | | @cuenti-cn/button | Componente Button | npm install @cuenti-cn/button | ~8KB |

Próximos componentes en desarrollo:

  • @cuenti-cn/input - Componente de entrada de texto
  • @cuenti-cn/card - Componente de tarjeta
  • @cuenti-cn/modal - Componente modal/dialog

🎨 Configuración de Estilos

Configuración Automática

Al instalar cualquier paquete, se ejecutará automáticamente un script que:

  1. 🔍 Detecta tu archivo CSS global (globals.css, global.css, index.css, etc.)
  2. 💾 Crea una copia de seguridad del archivo existente
  3. ❓ Te pregunta si deseas sobrescribirlo con los estilos de Cuenti CN UI
  4. ✅ Aplica los estilos necesarios para que los componentes funcionen correctamente

Configuración Manual

Si prefieres configurar manualmente los estilos:

/* En tu archivo CSS principal */
@import 'cuenti-cn-ui/styles';

/* O si usas componentes individuales */
@import '@cuenti-cn/core/styles';

📦 Uso

Uso de la Librería Completa

import { Button } from 'cuenti-cn-ui'

function App() {
  return (
    <Button variant="default" size="lg">
      ¡Hola Mundo!
    </Button>
  )
}

Uso de Componentes Individuales

import { Button } from '@cuenti-cn/button'

function App() {
  return <Button variant="outline">Botón Individual</Button>
}

Importación de Utilidades

import { cn } from '@cuenti-cn/core'

// Uso de la función de utilidad para combinar clases
const buttonClass = cn('base-button-classes', condition && 'conditional-classes')

/_ O si usas componentes individuales _/ @import '@cuenti-cn/core/styles';


## 📦 Uso

### Uso de la Librería Completa

```tsx
import { Button } from 'cuenti-cn-ui'

function App() {
  return (
    <Button variant="default" size="lg">
      ¡Hola Mundo!
    </Button>
  )
}

Uso de Componentes Individuales

import { Button } from '@cuenti-cn/button'

function App() {
  return <Button variant="outline">Botón Individual</Button>
}

Importación de Utilidades

import { cn } from '@cuenti-cn/core'

// Uso de la función de utilidad para combinar clases
const buttonClass = cn('base-button-classes', condition && 'conditional-classes')

Ejemplos de Instalación y Uso

Caso 1: Proyecto nuevo con todos los componentes

# Instalación
npm install cuenti-cn-ui

# Uso
import { Button } from 'cuenti-cn-ui'

Caso 2: Proyecto con bundle optimization

# Instalación granular
npm install @cuenti-cn/core @cuenti-cn/button

# Uso
import { Button } from '@cuenti-cn/button'
import { cn } from '@cuenti-cn/core'

Caso 3: Añadir un componente a proyecto existente

# Si ya tienes @cuenti-cn/core
npm install @cuenti-cn/button

# Si es tu primer componente individual
npm install @cuenti-cn/core @cuenti-cn/button

🧱 Componentes Disponibles

Button

Un componente de botón versátil con múltiples variantes y tamaños.

import { Button } from 'cuenti-cn-ui'
// o
import { Button } from '@cuenti-cn/button'

// Variantes disponibles
<Button variant="default">Default</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>

// Tamaños disponibles
<Button size="sm">Pequeño</Button>
<Button size="default">Default</Button>
<Button size="lg">Grande</Button>
<Button size="icon">🔍</Button>

Props del Button

| Prop | Tipo | Default | Descripción | | -------------------- | ----------------------------------------------------------------------------- | ----------- | --------------------------------------------------- | | variant | 'default' \| 'destructive' \| 'outline' \| 'secondary' \| 'ghost' \| 'link' | 'default' | Estilo visual del botón | | size | 'default' \| 'sm' \| 'lg' \| 'icon' | 'default' | Tamaño del botón | | asChild | boolean | false | Renderiza como un componente hijo usando Radix Slot | | accessibilityLabel | string | - | Label de accesibilidad (requerido para size="icon") |

🛠️ Desarrollo

Ejecutar Storybook

pnpm storybook

Build de la librería

# Build completo (librería + paquetes individuales)
pnpm build

# Solo paquetes individuales
pnpm build:packages

Linting y Formateo

pnpm lint
pnpm format

➕ Añadir Nuevos Componentes

Estructura para Nuevos Componentes

Para añadir un nuevo componente, sigue esta estructura de directorios:

packages/
├── tu-nuevo-componente/
│   ├── package.json
│   ├── tsconfig.json
│   ├── rollup.config.js
│   └── src/
│       ├── index.ts
│       └── tu-componente.tsx

Paso a Paso: Crear un Nuevo Componente

1. Crear la estructura del paquete

# Desde la raíz del proyecto
mkdir packages/mi-componente
cd packages/mi-componente

2. Crear package.json

{
  "name": "@cuenti-cn/mi-componente",
  "version": "0.0.1",
  "type": "module",
  "description": "Mi Componente para Cuenti CN UI",
  "main": "dist/index.js",
  "module": "dist/index.esm.js",
  "types": "dist/index.d.ts",
  "files": ["dist"],
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.esm.js",
      "require": "./dist/index.js"
    }
  },
  "scripts": {
    "build": "rollup -c",
    "type-check": "tsc --noEmit"
  },
  "peerDependencies": {
    "react": ">=18.0.0",
    "react-dom": ">=18.0.0"
  },
  "dependencies": {
    "@cuenti-cn/core": "workspace:*",
    "@radix-ui/react-slot": "1.2.3",
    "class-variance-authority": "0.7.1"
  },
  "devDependencies": {
    "@rollup/plugin-commonjs": "^28.0.1",
    "@rollup/plugin-node-resolve": "^15.3.0",
    "@rollup/plugin-typescript": "^12.1.1",
    "@types/react": "19.1.13",
    "@types/react-dom": "19.1.9",
    "rollup": "^4.28.1",
    "rollup-plugin-dts": "^6.1.1",
    "tslib": "^2.6.0",
    "typescript": "5.9.2"
  },
  "keywords": ["react", "mi-componente", "component", "ui", "tailwind"],
  "author": "Cuenti",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/Cuenti/cuenti-cn-ui.git",
    "directory": "packages/mi-componente"
  }
}

3. Crear tsconfig.json

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src",
    "jsx": "react-jsx",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["**/*.test.*", "**/*.stories.*"]
}

4. Crear rollup.config.js

import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from '@rollup/plugin-typescript'
import dts from 'rollup-plugin-dts'

const external = [
  'react',
  'react-dom',
  'react/jsx-runtime',
  '@radix-ui/react-slot',
  'class-variance-authority',
  'class-variance-authority/types',
  '@cuenti-cn/core',
  'tslib'
]

export default [
  {
    input: 'src/index.ts',
    output: [
      {
        file: 'dist/index.js',
        format: 'cjs',
        sourcemap: true
      },
      {
        file: 'dist/index.esm.js',
        format: 'esm',
        sourcemap: true
      }
    ],
    plugins: [
      resolve({
        preferBuiltins: false
      }),
      commonjs(),
      typescript({
        tsconfig: './tsconfig.json',
        declaration: false,
        importHelpers: true
      })
    ],
    external
  },
  {
    input: 'src/index.ts',
    output: {
      file: 'dist/index.d.ts',
      format: 'esm'
    },
    plugins: [dts()],
    external
  }
]

5. Crear el componente

src/mi-componente.tsx:

import * as React from 'react'
import { Slot } from '@radix-ui/react-slot'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@cuenti-cn/core'

const miComponenteVariants = cva(
  'base-classes', // Clases base de Tailwind
  {
    variants: {
      variant: {
        default: 'default-variant-classes',
        secondary: 'secondary-variant-classes'
      },
      size: {
        default: 'default-size-classes',
        sm: 'small-size-classes',
        lg: 'large-size-classes'
      }
    },
    defaultVariants: {
      variant: 'default',
      size: 'default'
    }
  }
)

export type MiComponenteProps = React.ComponentProps<'div'> &
  VariantProps<typeof miComponenteVariants> & {
    asChild?: boolean
  }

function MiComponente({
  className,
  variant,
  size,
  asChild = false,
  children,
  ...props
}: MiComponenteProps) {
  const Comp = asChild ? Slot : 'div'

  return (
    <Comp className={cn(miComponenteVariants({ variant, size, className }))} {...props}>
      {children}
    </Comp>
  )
}

export { MiComponente, miComponenteVariants }

src/index.ts:

export { MiComponente, miComponenteVariants } from './mi-componente'
export type { MiComponenteProps } from './mi-componente'

6. Crear Storybook (Opcional)

src/mi-componente.stories.tsx:

import type { Meta, StoryObj } from '@storybook/react'
import { MiComponente } from './mi-componente'

const meta: Meta<typeof MiComponente> = {
  title: 'Components/MiComponente',
  component: MiComponente,
  parameters: {
    layout: 'centered'
  },
  tags: ['autodocs'],
  argTypes: {
    variant: {
      control: { type: 'select' },
      options: ['default', 'secondary']
    }
  }
}

export default meta
type Story = StoryObj<typeof meta>

export const Default: Story = {
  args: {
    children: 'Mi Componente'
  }
}

export const Secondary: Story = {
  args: {
    variant: 'secondary',
    children: 'Mi Componente Secundario'
  }
}

7. Añadir al paquete principal

Actualiza src/index.ts en la raíz:

// Exports existentes...
export { MiComponente, miComponenteVariants } from '@cuenti-cn/mi-componente'
export type { MiComponenteProps } from '@cuenti-cn/mi-componente'

Actualiza package.json principal para incluir el nuevo export:

{
  "exports": {
    // ... exports existentes
    "./mi-componente": {
      "types": "./packages/mi-componente/dist/index.d.ts",
      "import": "./packages/mi-componente/dist/index.esm.js",
      "require": "./packages/mi-componente/dist/index.js"
    }
  }
}

8. Build y test

# Instalar dependencias
pnpm install

# Build del nuevo componente
cd packages/mi-componente
pnpm build

# Build completo
cd ../..
pnpm build

# Test en Storybook
pnpm storybook

Publicar el Nuevo Componente

# Desde packages/mi-componente
npm publish --access public

💡 Mejores Prácticas

Instalación Recomendada por Tipo de Proyecto

| Tipo de Proyecto | Recomendación | Razón | | ------------------------------ | ----------------------------------------- | ----------------------------------------------------- | | Proyecto pequeño/prototipo | npm install cuenti-cn-ui | Instalación rápida, todos los componentes disponibles | | Aplicación en producción | Instalación individual por componente | Bundle más pequeño, mejor performance | | Librería/paquete NPM | Instalación individual | Evita dependencias innecesarias | | Aplicación empresarial | Instalación individual + alias de imports | Máximo control y optimización |

Optimización de Bundle

// ✅ Buena práctica - importación específica
import { Button } from '@cuenti-cn/button'
import { cn } from '@cuenti-cn/core'

// ❌ Evitar - importación completa innecesaria
import { Button } from 'cuenti-cn-ui' // Si solo necesitas Button

Alias de Importación (Recomendado para proyectos grandes)

// tsconfig.json o vite.config.ts
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@ui/*": ["node_modules/@cuenti-cn/*/src"],
      "@ui/core": ["node_modules/@cuenti-cn/core/src"]
    }
  }
}
// Uso con alias
import { Button } from '@ui/button'
import { cn } from '@ui/core'

🔧 Troubleshooting

Problema: Estilos no se aplican

Solución:

  1. Verifica que hayas importado los estilos:
    @import '@cuenti-cn/core/styles';
  2. Asegúrate de que Tailwind CSS esté configurado en tu proyecto
  3. Ejecuta el script postinstall manualmente:
    node node_modules/@cuenti-cn/core/scripts/postinstall.js

Problema: Tipos TypeScript no funcionan

Solución:

  1. Asegúrate de tener @types/react instalado
  2. Verifica que moduleResolution esté en "bundler" o "node"
  3. Añade a tu tsconfig.json:
    {
      "compilerOptions": {
        "skipLibCheck": true
      }
    }

Problema: Build errors con "Cannot resolve module"

Solución:

  1. Instala @cuenti-cn/core si usas componentes individuales
  2. Verifica que todas las peerDependencies estén instaladas:
    npm install react react-dom @types/react @types/react-dom

Problema: Bundle muy grande

Solución:

  1. Usa instalación individual en lugar del paquete completo
  2. Implementa tree-shaking en tu bundler
  3. Verifica que uses importaciones específicas, no wildcard imports

🔄 Versionado y Actualizaciones

Estrategia de Versionado

Seguimos Semantic Versioning:

  • Patch (0.0.x): Bug fixes y mejoras menores
  • Minor (0.x.0): Nuevos componentes y features
  • Major (x.0.0): Breaking changes

Actualizar Componentes

# Actualizar todos los paquetes de Cuenti CN UI
npm update cuenti-cn-ui @cuenti-cn/core @cuenti-cn/button

# Actualizar un componente específico
npm update @cuenti-cn/button

# Verificar versiones instaladas
npm list | grep cuenti-cn

Migración entre Versiones Mayores

Consulta siempre el CHANGELOG.md para guías de migración detalladas entre versiones mayores.

📖 Documentación

🤝 Contribuir

Las contribuciones son bienvenidas. Por favor:

  1. Haz fork del repositorio
  2. Crea una rama para tu feature (git checkout -b feature/nueva-caracteristica)
  3. Commit tus cambios (git commit -am 'Añadir nueva característica')
  4. Push a la rama (git push origin feature/nueva-caracteristica)
  5. Abre un Pull Request

📄 Licencia

MIT © Cuenti

🙏 Agradecimientos