akademiapp-shared-components
v1.0.24
Published
`akademiapp-shared-components` es una librería de componentes reutilizables diseñada para ser usada en proyectos de **React**, **React Native**, y **React Native Web**. Proporciona componentes estilizados de forma flexible, con soporte para personalizació
Downloads
40
Readme
AkademiApp Shared Components
akademiapp-shared-components
es una librería de componentes reutilizables diseñada para ser usada en proyectos de React, React Native, y React Native Web. Proporciona componentes estilizados de forma flexible, con soporte para personalización de colores y tamaños, y compatibilidad tanto para web como para dispositivos móviles utilizando Tailwind CSS y tailwind-rn.
Características principales
- Compatibilidad multiplataforma: los componentes funcionan en React, React Native, y React Native Web.
- Estilos personalizables: cada componente admite la personalización de colores y tamaños sin necesidad de modificar la configuración global.
- Estilos basados en Tailwind CSS: la librería utiliza Tailwind CSS para los estilos en la web, proporcionando flexibilidad y simplicidad.
- Fácil de usar: cada componente es fácil de implementar, con una interfaz clara y extensible.
- Optimizado para librerías: configuración adecuada para publicar como paquete npm, incluyendo estilos y tipados.
Instalación
Para usar esta librería en tu proyecto de React, React Native, o React Native Web, primero instala el paquete usando yarn
:
yarn add akademiapp-shared-components
Dependencias
- React: ^18.3.1
- React Native: ^0.73.0
- Tailwind CSS: ^3.4.13 (para estilos en la web)
- tailwind-rn: para usar Tailwind en React Native
Uso de los componentes
Botón (Button)
El componente Button es un botón reutilizable y personalizable que admite diferentes variantes, tamaños y colores.
Props
| Prop | Tipo | Descripción | Valores por defecto | |-----------|--------------------------|---------------------------------------------------------------------------|---------------------| | variant | 'primary' | 'outline' | Controla la apariencia del botón. | 'primary' | | size | 'sm' | 'md' | 'lg' | Define el tamaño del botón. | 'md' | | color | string | Color de fondo para el botón en la variante primary, o el borde en la variante outline. | '#8287FF' | | textColor | string | Color del texto del botón, cuando se usa la variante outline. | '#FFFFFF' | | onPress | () => void | Función que se ejecuta cuando el botón es presionado. | undefined | | children | React.ReactNode | Contenido dentro del botón, que puede ser texto u otros elementos. | undefined |
Ejemplo
React Native Web y React
import React from 'react';
import { Button } from 'akademiapp-shared-components';
import { PlusCircle } from 'lucide-react';
const MyComponent = () => (
<Button
variant="primary"
size="lg"
color="#8287FF"
onPress={() => console.log('Button clicked!')}
>
<PlusCircle className="w-4 h-4" />
Agregar
</Button>
);
export default MyComponent;
Configuración de Tailwind CSS
Esta librería utiliza Tailwind CSS para los estilos en la web. Asegúrate de que tu proyecto esté configurado correctamente para usar Tailwind CSS al consumir esta librería.
Paso 1: Instalar Tailwind CSS
Si aún no lo has hecho, instala Tailwind CSS en tu proyecto:
yarn add -D tailwindcss postcss autoprefixer
Inicializa Tailwind CSS:
npx tailwindcss init -p
Paso 2: Configurar tailwind.config.js
Asegúrate de que tailwind.config.js incluya los paths a los archivos de tu proyecto y a los archivos de la librería:
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{js,jsx,ts,tsx}',
'./node_modules/akademiapp-shared-components/dist/**/*.js',
],
theme: {
extend: {},
},
plugins: [],
};
Paso 3: Crear e Importar index.css
Crea un archivo index.css en tu proyecto con las directivas de Tailwind:
/* index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Importa este archivo en tu entrada principal (por ejemplo, index.tsx):
// src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css'; // Importa Tailwind CSS
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Manejo del error: Could not resolve "react-native"
Al usar esta librería en un proyecto que no es React Native, es posible que encuentres el siguiente error:
[ERROR] Could not resolve "react-native"
node_modules/akademiapp-shared-components/dist/components/ui/Button.js:8:29:
8 │ var react_native_1 = require("react-native");
╵ ~~~~~~~~~~~~~~
Solución
Este error ocurre porque el bundler no puede resolver el módulo react-native, que es específico para aplicaciones móviles. Para resolverlo, debes configurar tu bundler (por ejemplo, Vite) para alias react-native a react-native-web y marcarlo como externo.
Configuración de Vite
Añade el siguiente archivo vite.config.js en el proyecto donde estás usando la librería:
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'react-native': 'react-native-web',
},
},
build: {
rollupOptions: {
external: ['react-native'], // Marca "react-native" como externo para evitar el error
},
},
});
Paso a Paso
Crear o editar vite.config.js:
Asegúrate de que tu configuración de Vite incluye el alias y la marca de react-native como externo.
Instalar react-native-web:
Si aún no lo has hecho, instala react-native-web en tu proyecto:
yarn add react-native-web
Verificar la configuración:
Asegúrate de que react-native está correctamente aliasado a react-native-web en vite.config.js y que está marcado como externo.
Creación de nuevos componentes
Para crear nuevos componentes en esta librería, sigue estos pasos asegurándote de que utilices Tailwind CSS para los estilos y manteniendo la compatibilidad multiplataforma.
Paso 1: Crear el Componente
Crea un nuevo archivo en src/components/ui/, por ejemplo, Card.tsx:
// src/components/ui/Card.tsx
import React from 'react';
import { Platform, View, Text, TouchableOpacity, ViewStyle, TextStyle } from 'react-native';
interface CardProps {
title: string;
description: string;
variant?: 'info' | 'warning' | 'success';
onPress?: () => void;
}
const Card: React.FC<CardProps> = ({ title, description, variant = 'info', onPress }) => {
const colorMap = {
info: '#2A2870',
warning: '#FFC107',
success: '#28A745',
};
if (Platform.OS === 'web' && typeof window !== 'undefined' && window.document) {
const cardClasses = `p-4 rounded-lg shadow-md ${
variant === 'info' ? 'bg-blue-100 border border-blue-500' :
variant === 'warning' ? 'bg-yellow-100 border border-yellow-500' :
'bg-green-100 border border-green-500'
}`;
return (
<div className={cardClasses} onClick={onPress}>
<h3 className="text-lg font-bold mb-2">{title}</h3>
<p className="text-gray-700">{description}</p>
</div>
);
}
const baseStyle: ViewStyle = {
padding: 16,
borderRadius: 8,
backgroundColor: '#F0F4FF',
borderWidth: 1,
borderColor: colorMap[variant],
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 2,
};
const titleStyle: TextStyle = {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 8,
color: colorMap[variant],
};
const descriptionStyle: TextStyle = {
fontSize: 14,
color: '#333333',
};
return (
<TouchableOpacity onPress={onPress} style={baseStyle}>
<Text style={titleStyle}>{title}</Text>
<Text style={descriptionStyle}>{description}</Text>
</TouchableOpacity>
);
};
export { Card };
export default Card;
Paso 2: Actualizar el index.ts
Exporta el nuevo componente en src/index.ts:
// src/index.ts
import './index.css'; // Importa los estilos de Tailwind
export { Button } from './components/ui/Button';
export { Card } from './components/ui/Card';
export { someUtility } from './utils/someUtility';
Paso 3: Actualizar los scripts de build
Asegúrate de que los nuevos componentes y sus estilos se copien correctamente en la carpeta dist. Actualiza el script de build en package.json para copiar todo el CSS necesario:
"scripts": {
"build": "tsc && cpy \"src/index.css\" dist && cpy \"src/components/ui/*.css\" dist/components/ui",
"clean": "rimraf dist"
}
Paso 4: Usar el nuevo componente
Ahora puedes usar el componente Card en tus proyectos:
// src/stories/Card.stories.tsx
import React from 'react';
import { Meta, Story } from '@storybook/react';
import { Card } from 'akademiapp-shared-components';
const meta: Meta = {
title: 'UI/Card',
component: Card,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
variant: {
control: { type: 'radio' },
options: ['info', 'warning', 'success'],
description: 'Elige el estilo del card',
},
onPress: { action: 'clicked' },
},
};
export default meta;
const Template: Story = (args) => <Card {...args} />;
export const Info = Template.bind({});
Info.args = {
title: 'Información',
description: 'Este es un card de información.',
variant: 'info',
};
export const Warning = Template.bind({});
Warning.args = {
title: 'Advertencia',
description: 'Este es un card de advertencia.',
variant: 'warning',
};
export const Success = Template.bind({});
Success.args = {
title: 'Éxito',
description: 'Este es un card de éxito.',
variant: 'success',
};
Construcción y despliegue
Para construir la librería y generar los archivos en la carpeta dist, puedes usar el siguiente comando:
yarn build
Scripts de package.json
{
"scripts": {
"build": "tsc && cpy \"src/index.css\" dist && cpy \"src/components/ui/*.css\" dist/components/ui",
"clean": "rimraf dist"
}
}
¿Qué contiene el build?
La carpeta dist incluye:
- Componentes compilados en JavaScript.
- Archivos .d.ts generados para la comprobación de tipos.
- Archivos CSS necesarios para los estilos.
Resolución de errores comunes
Error: Could not resolve "react-native"
Al usar esta librería en un proyecto que no es React Native, es posible que encuentres el siguiente error:
[ERROR] Could not resolve "react-native"
node_modules/akademiapp-shared-components/dist/components/ui/Button.js:8:29:
8 │ var react_native_1 = require("react-native");
╵ ~~~~~~~~~~~~~~
Solución
Este error ocurre porque el bundler no puede resolver el módulo react-native, que es específico para aplicaciones móviles. Para resolverlo, debes configurar tu bundler (por ejemplo, Vite) para alias react-native a react-native-web y marcarlo como externo.
Configuración de Vite
Añade el siguiente archivo vite.config.js en el proyecto donde estás usando la librería:
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'react-native': 'react-native-web',
},
},
build: {
rollupOptions: {
external: ['react-native'], // Marca "react-native" como externo para evitar el error
},
},
});
Este ajuste permite que react-native sea tratado como un módulo externo y evita que el bundler intente resolverlo, eliminando así el error.
Scripts
- build: Compila los archivos de TypeScript y copia los archivos CSS necesarios a la carpeta dist.
- clean: Elimina la carpeta dist.
Contribuciones
Si deseas contribuir a esta librería, sigue estos pasos:
Clona el repositorio:
git clone https://github.com/tu-usuario/akademiapp-shared-components.git cd akademiapp-shared-components
Crea una rama nueva:
git checkout -b feature/nueva-funcionalidad
Realiza tus cambios.
Instala las dependencias:
yarn install
Construye y prueba tu librería:
yarn build
Realiza un commit y push:
git add . git commit -m "Descripción de los cambios" git push origin feature/nueva-funcionalidad
Historias de Storybook
Esta librería proporciona historias para todos sus componentes utilizando Storybook, lo que permite una fácil documentación visual y pruebas interactivas. Las historias se copian automáticamente a la carpeta .storybook/akademi-shared-components
del proyecto.
Paso para Integrar las Historias en tu Proyecto
Asegúrate de tener Storybook instalado en tu proyecto:
npx sb init
Modifica el archivo .storybook/main.js
para incluir las historias copiadas:
module.exports = {
stories: [
'../src/**/*.stories.@(js|jsx|ts|tsx|mdx)',
'.storybook/akademi-shared-components/**/*.stories.@(js|jsx|ts|tsx|mdx)',
],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
],
framework: '@storybook/react',
};
Ejecuta Storybook:
yarn storybook