Librería de componentes React con Tailwind CSS, diseñada siguiendo las mejores prácticas de Clean Code y principios SOLID.
npm install react-card-component-librarybash
Clonar el repositorio
git clone [url-del-repositorio]
cd react-card-component-library
Instalar dependencias
npm install
`
🛠️ Scripts Disponibles
$3
`bash
npm run dev # Inicia servidor de desarrollo (http://localhost:5173)
npm run storybook # Inicia Storybook (http://localhost:6006)
`
$3
`bash
npm run test # Ejecuta tests unitarios
npm run test:ui # Ejecuta tests con interfaz visual
npm run test:coverage # Genera reporte de cobertura
`
$3
`bash
npm run build # Construye para producción
npm run build-storybook # Construye Storybook estático
npm run lint # Ejecuta ESLint
`
🧩 Componente Card
$3
| Prop | Tipo | Default | Descripción |
| --------------- | ---------------------------------------- | ----------- | ----------------------------------------- |
| title | string | - | Título de la tarjeta (requerido) |
| description | string | - | Descripción de la tarjeta (requerido) |
| imageUrl | string | undefined | URL de la imagen |
| imageAlt | string | title | Texto alternativo para la imagen |
| buttonText | string | 'Ver más' | Texto del botón |
| onButtonClick | () => void | undefined | Callback al hacer click en el botón |
| variant | 'primary' \| 'secondary' \| 'outlined' | 'primary' | Variante de estilo |
| size | 'small' \| 'medium' \| 'large' | 'medium' | Tamaño de la tarjeta |
| className | string | undefined | Clases CSS adicionales |
$3
`tsx
import { Card } from "@/components";
function App() {
return (
title="Mi Tarjeta"
description="Esta es una descripción de ejemplo"
imageUrl="https://example.com/image.jpg"
imageAlt="Descripción de la imagen"
buttonText="Leer más"
onButtonClick={() => console.log("Click!")}
variant="primary"
size="medium"
className="custom-class"
/>
);
}
`
🎨 Variantes
$3
Borde azul con botón azul - ideal para acciones principales
$3
Borde gris con botón gris - ideal para acciones secundarias
$3
Borde gris claro con botón azul - ideal para estilos sutiles
📏 Tamaños
- Small: 250px max-width - perfecto para sidebars
- Medium: 350px max-width (por defecto) - uso general
- Large: 450px max-width - destacar contenido importante
🎭 Storybook
Visualiza todos los estados del componente:
`bash
npm run storybook
`
Abre http://localhost:6006 para ver:
- ✨ Todas las variantes
- 📐 Todos los tamaños
- 🎯 Diferentes estados
- 📚 Documentación interactiva
✅ Testing
$3
El componente incluye tests exhaustivos que cubren:
- ✅ Renderizado con props básicas
- ✅ Renderizado con imagen
- ✅ Click en botón
- ✅ Sin botón cuando no hay callback
- ✅ Variantes de estilo (primary, secondary, outlined)
- ✅ Tamaños (small, medium, large)
- ✅ Clases personalizadas
- ✅ Accesibilidad (ARIA labels)
`bash
Ejecutar todos los tests
npm run test
Modo watch
npm run test -- --watch
Con UI
npm run test:ui
Con coverage
npm run test:coverage
`
🏗️ Estructura del Proyecto
`
react-card-component-library/
├── .storybook/ # Configuración de Storybook
├── .vscode/ # Configuración del workspace
│ ├── settings.json
│ └── extensions.json
├── src/
│ ├── components/
│ │ └── Card/
│ │ ├── Card.tsx # Componente principal
│ │ ├── Card.test.tsx # Tests unitarios
│ │ ├── Card.stories.tsx # Storybook stories
│ │ └── index.ts # Exportaciones
│ ├── types/
│ │ └── index.ts # TypeScript types
│ ├── utils/
│ │ ├── cn.ts # Utilidad para Tailwind
│ │ └── index.ts
│ ├── tests/
│ │ └── setup.ts # Configuración de tests
│ ├── App.tsx # Aplicación de ejemplo
│ ├── main.tsx # Entry point
│ └── index.css # Tailwind imports
├── tailwind.config.js # Configuración de Tailwind
├── vite.config.ts # Configuración de Vite
├── tsconfig.json # Configuración de TypeScript
├── package.json
└── README.md
`
🎯 Mejores Prácticas Aplicadas
$3
- ✨ Nombres descriptivos y semánticos
- 🎯 Funciones pequeñas y enfocadas (SRP)
- 📝 Comentarios cuando aportan valor
- 🔍 Código autoexplicativo y legible
$3
#### Single Responsibility
Cada componente tiene una sola responsabilidad. El componente Card solo se encarga de mostrar una tarjeta.
#### Open/Closed
Extensible mediante props (variant, size, className) sin modificar el código fuente.
#### Liskov Substitution
Props opcionales con valores por defecto garantizan que el componente funcione en cualquier contexto.
#### Interface Segregation
Interfaces TypeScript específicas y mínimas (CardProps).
#### Dependency Inversion
Depende de abstracciones (tipos TypeScript) en lugar de implementaciones concretas.
$3
- ♿ ARIA labels en botones (aria-label)
- 🖼️ Imágenes con alt text descriptivo
- 🏷️ Semántica HTML correcta (h3, button, p)
- 👁️ Estados de focus visibles
- ⌨️ Navegación por teclado
🔧 Tecnologías
- React 19 - Librería UI
- TypeScript 5 - Type safety
- Tailwind CSS 4 - Estilos utility-first
- Vite 7 - Build tool y dev server
- Vitest 4 - Testing framework
- Testing Library - Testing utilities
- Storybook 10 - Documentación de componentes
- clsx + tailwind-merge - Manejo de clases CSS
📝 Notas de Desarrollo
$3
Puedes personalizar los colores, sombras y más en tailwind.config.js:
`js
theme: {
extend: {
colors: {
primary: {
500: '#3b82f6', // Cambia el color principal
// ... más colores
}
},
boxShadow: {
'card': '0 2px 8px rgba(0, 0, 0, 0.1)',
}
}
}
`
$3
Usa la prop className para añadir estilos adicionales:
`tsx
title="Mi Tarjeta"
description="Descripción"
className="shadow-2xl ring-2 ring-purple-500"
/>
`
$3
La función cn() combina clsx y tailwind-merge para manejar clases condicionales y evitar conflictos:
`tsx
import { cn } from "@/utils";
// Combina clases sin conflictos
cn("base-class", condition && "conditional-class", className);
`
🚀 Despliegue
$3
`bash
npm run build
`
Los archivos optimizados se generarán en dist/.
$3
`bash
npm run build-storybook
`
Los archivos estáticos de Storybook se generarán en storybook-static/.
📋 Checklist de Calidad
- ✅ TypeScript sin errores
- ✅ Tests con cobertura completa
- ✅ Accesibilidad verificada (a11y addon)
- ✅ ESLint sin warnings
- ✅ Storybook con todas las variantes
- ✅ Documentación completa
- ✅ Ejemplos funcionales
🤝 Contribuir
1. Fork el proyecto
2. Crea una rama para tu feature (git checkout -b feature/AmazingFeature)
3. Commit tus cambios (git commit -m 'Add some AmazingFeature')
4. Push a la rama (git push origin feature/AmazingFeature`)