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

@tipmexico/tm_theme

v2.0.0

Published

module that contain design system

Readme

TM Theme - Sistema de Diseño

Información del Proyecto

| Propiedad | Valor | | --------------- | --------------------------------------------------------- | | Nombre | @tipmexico/tm_theme | | Versión | 1.2.34 | | Repositorio | Bitbucket |


Resumen Ejecutivo

TM Theme es un sistema de diseño (Design System) completo y robusto para aplicaciones web y móviles de TipMéxico, construido con React Native y Expo. Implementa la metodología Atomic Design y proporciona una biblioteca completa de componentes reutilizables, tematización multi-marca y tokens de diseño consistentes para garantizar:

  • Consistencia visual entre plataformas (Web, iOS, Android)
  • Desarrollo acelerado con componentes pre-construidos
  • Tematización dinámica multi-marca
  • Accesibilidad y mejores prácticas de UX
  • Type safety completo con TypeScript
  • Documentación interactiva con Storybook

Características Principales

Arquitectura de Diseño

  • Atomic Design - Metodología de diseño escalable
  • Design Tokens - Sistema de tokens para colores, tipografía, espaciado
  • Multi-Brand Theming - Soporte para múltiples marcas (Bitcar, TIP, OFS)
  • Component-Driven Development - Componentes aislados y reutilizables

Plataformas Soportadas

  • Web - React 19+
  • iOS - iOS 13+
  • Android - API 21+

Tecnologías Core

  • TypeScript 5.x - Type safety completo
  • React Native 0.79.5 - Framework multi-plataforma
  • Expo 53 - Toolchain y SDK
  • Storybook 9.x - Documentación interactiva
  • React Native SVG - Iconografía vectorial
  • Poppins & Roboto - Tipografía personalizada

Arquitectura del Sistema

Metodología Atomic Design

┌─────────────────────────────────────────────────────────────┐
│                       TEMPLATES                             │
│              (Estructuras de página completa)               │
│  - LoginTemplate                                            │
│  - Layouts completos                                        │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│                      ORGANISMS                              │
│              (Secciones complejas de UI)                    │
│  - Header                                                   │
│  - BottomNavigation                                         │
│  - CardStatusDetails                                        │
│  - CardTitleDetails                                         │
│  - ModalSearchMaintenance                                   │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│                      MOLECULES                              │
│              (Grupos de componentes)                        │
│  - Accordion                                                │
│  - Modal                                                    │
│  - Pagination                                               │
│  - FileUploader                                             │
│  - CardActions, CardMetrics, CardTimeline                   │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│                        ATOMS                                │
│              (Componentes fundamentales)                    │
│  - Button, TextField, Checkbox, Dropdown                    │
│  - Avatar, Badge, Alert, Spinner                            │
│  - Icon, Card, Label, Switch                                │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│                    DESIGN TOKENS                            │
│              (Valores fundamentales)                        │
│  - Colors (Paletas de marca)                                │
│  - Typography (Heading, Paragraph, Button)                  │
│  - Spacing (none, xxs, xs, sm, md, lg, xl, 2xl-6xl)        │
│  - Radius (Bordes redondeados)                              │
└─────────────────────────────────────────────────────────────┘

Inventario de Componentes

Atoms (27 Componentes Fundamentales)

Componentes básicos e indivisibles que forman la base del sistema:

| Componente | Descripción | Casos de Uso | | --------------- | ----------------------------------- | --------------------------------- | | Alert | Mensajes de alerta y notificaciones | Errores, advertencias, info | | Avatar | Imagen de perfil circular | Perfiles de usuario | | Badge | Etiquetas y contadores | Notificaciones, estados | | BreadCrumbs | Navegación de ruta | Navegación jerárquica | | Button | Botones de acción | CTAs, formularios | | Card | Contenedor de información | Tarjetas de contenido | | Checkbox | Selección múltiple | Formularios, filtros | | DatePicker | Selector de fecha | Formularios de fecha | | Divisor | Separador visual | Secciones, grupos | | Dropdown | Selector desplegable | Menús, selección de opciones | | Icon | Iconos vectoriales | Decoración, navegación | | IconButton | Botón solo con icono | Acciones rápidas | | InfoDetail | Detalle de información | Datos estructurados | | Label | Etiquetas de texto | Formularios, identificadores | | ProgressBar | Barra de progreso | Carga, completitud | | RadioButton | Selección única | Formularios, opciones excluyentes | | RatingStars | Calificación con estrellas | Reviews, valoraciones | | Skeleton | Placeholder de carga | Loading states | | Spinner | Indicador de carga circular | Loading, procesamiento | | Steper | Indicador de pasos | Wizards, procesos multi-paso | | Switch | Interruptor on/off | Configuraciones, toggles | | Tab | Pestañas de navegación | Vistas alternativas | | TextArea | Entrada de texto multilínea | Comentarios, descripciones | | TextField | Entrada de texto | Formularios, búsqueda | | TextLink | Enlace de texto | Navegación, enlaces | | TimePicker | Selector de hora | Agendamiento | | Tooltip | Ayuda contextual | Información adicional |


Molecules (14 Componentes Compuestos)

Grupos de átomos que forman componentes funcionales más complejos:

| Componente | Descripción | Componentes Utilizados | | --------------------- | ------------------------------------- | ------------------------- | | Accordion | Panel expandible/colapsable | Icon, Label, Card | | CardActions | Tarjeta con acciones | Card, Button, Icon | | CardMetrics | Tarjeta de métricas/estadísticas | Card, Label, Icon | | CardStatus | Tarjeta con indicador de estado | Card, Badge, Label | | CardTimeline | Tarjeta de línea de tiempo | Card, Timeline | | CardTitle | Tarjeta con título y subtítulo | Card, Label | | EdgeCases | Componentes para estados vacíos/error | Icon, Label, Button | | FileUploader | Cargador de archivos | Button, Icon, ProgressBar | | Modal | Ventana modal | Card, Button, IconButton | | ModalConfirmation | Modal de confirmación | Modal, Button | | Pagination | Paginación de contenido | Button, Label, Icon | | SnackBar | Notificación temporal | Alert, Icon | | TableStriped | Tabla con filas alternadas | Card, Label | | Timeline | Línea de tiempo | Icon, Label, Divisor |


Organisms (5 Componentes Complejos)

Secciones complejas de UI que combinan múltiples moléculas:

| Componente | Descripción | Casos de Uso | | -------------------------- | ---------------------------------- | ------------------------ | | BottomNavigation | Navegación inferior móvil | Apps móviles, navegación | | CardStatusDetails | Tarjeta con detalles de estado | Dashboard, seguimiento | | CardTitleDetails | Tarjeta con título y detalles | Información de entidades | | Header | Encabezado de aplicación | Navegación, branding | | ModalSearchMaintenance | Modal de búsqueda de mantenimiento | Búsqueda especializada |


Templates (1 Plantilla)

Estructuras de página completa:

| Template | Descripción | Casos de Uso | | ----------------- | ----------------------------------- | ------------------------- | | LoginTemplate | Plantilla completa de inicio sesión | Autenticación, onboarding |


Sistema de Iconografía

El módulo incluye 60+ iconos vectoriales SVG personalizados y optimizados:

Categorías de Iconos

Navegación y Acciones (16):

  • IconArrowLeft, IconArrowRight, IconUp, IconDown
  • IconHome, IconMenu, IconClose, IconBack
  • IconAdd, IconEdit, IconTrash, IconSearch
  • IconFilter, IconShare, IconSend, IconUpload, IconDownload

Documentos y Archivos (8):

  • IconDocument, IconDocumentAdd, IconDocumentNone
  • IconFolder, IconFolderAdd, IconImages, IconPhoto
  • IconDocumetPersonal

Vehículos y Mantenimiento (6):

  • IconCar, IconCarMaintenance, IconMaintenance
  • IconTools, IconFix, IconPackage

Comunicación (5):

  • IconChat, IconBell, IconPhone, IconMail, IconInfo

Usuario y Seguridad (7):

  • IconUsers, IconSecurity, IconSecurityLock
  • IconLogout, IconConfiguration, IconEye, IconEyeOff

Estado y Feedback (8):

  • IconCheck, IconLike, IconStar, IconStarFilled, IconStarHalfFilled
  • IconProblem, IconAccident, IconSlash

Tiempo y Calendario (5):

  • IconCalendar, IconCalendarContact, IconClock
  • IconClockHistory, IconPoint

Otros (5):

  • IconHelp, IconMoney, IconReport, IconPin, IconLess

Características de los Iconos

  • Formato: SVG vectorial escalable
  • Tamaños: Configurables (16px, 20px, 24px, 32px, 48px)
  • Colores: Adaptables a tema y contexto
  • Optimización: SVG optimizados para rendimiento

Sistema de Tematización

Marcas Soportadas

TM Theme soporta 3 marcas con temas personalizados:

| Marca | Descripción | Color Principal | | ---------- | -------------------------- | --------------- | | Bitcar | Marca principal de gestión | Personalizado | | TIP | TipMéxico brand | Personalizado | | OFS | OFS brand | Personalizado |

Cada marca tiene su propia paleta de colores, tipografía y tokens de diseño.

Design Tokens

1. Sistema de Colores

Colores Globales (compartidos entre marcas):

{
  black: '#000000',
  white: '#FFFFFF',
  transparent: 'transparent',

  // Estados
  green: '#10B981',      // Success
  greenLight: '#D1FAE5',
  red: '#EF4444',        // Error
  redLight: '#FEE2E2',
  blue: '#3B82F6',       // Info
  blueLight: '#DBEAFE',
  yellow: '#F59E0B',     // Warning
  yellowLight: '#FEF3C7',

  // Escala de grises
  gray: {
    1: '#F9FAFB',
    2: '#F3F4F6',
    3: '#E5E7EB',
    4: '#D1D5DB',
    5: '#9CA3AF',
    6: '#6B7280',
    7: '#4B5563',
    8: '#1F2937',
  },

  // Social
  greenWhatsapp: '#25D366',
}

Colores de Marca (específicos por marca):

{
  primary: string,      // Color principal de marca
  accents: {
    1: string,         // Acento primario
    2: string,         // Acento secundario
    3: string,         // Acento terciario
    4: string,         // Acento cuaternario
  }
}

2. Sistema Tipográfico

Familias de Fuentes:

  • Poppins - Títulos y headings
  • Roboto - Texto de párrafo y UI

Escalas Tipográficas:

Heading (Títulos):

{
  h1: 32,      // Display
  h2: 28,      // Page title
  h3: 24,      // Section title
  h4: 20,      // Card title
  h5: 18,      // Small title
  h6: 16,      // Subtitle
}

Paragraph (Párrafos):

{
  xlarge: 18,   // Destacado
  large: 16,    // Cuerpo principal
  regular: 14,  // Cuerpo estándar
  small: 12,    // Texto secundario
  xsmall: 10,   // Captions, notas
}

Button (Botones):

{
  large: 16,
  regular: 14,
  small: 12,
}

3. Sistema de Espaciado

Escala de espaciado consistente basada en múltiplos de 4px:

{
  none: 0,      // 0px
  xxs: 4,       // 4px
  xs: 8,        // 8px
  sm: 12,       // 12px
  md: 16,       // 16px  (base)
  lg: 20,       // 20px
  xl: 24,       // 24px
  '2xl': 32,    // 32px
  '3xl': 40,    // 40px
  '4xl': 48,    // 48px
  '5xl': 64,    // 64px
  '6xl': 80,    // 80px
}

4. Sistema de Bordes (Radius)

Escala de redondeo de bordes:

{
  none: 0,      // Cuadrado
  xxs: 2,       // Sutil
  xs: 4,        // Pequeño
  sm: 6,        // Mediano-pequeño
  md: 8,        // Mediano (estándar)
  lg: 12,       // Grande
  xl: 16,       // Extra grande
  '2xl': 20,    // Muy grande
  '3xl': 24,    // Pill
  '4xl': 32,    // Circular
  '5xl': 40,    // Circular grande
  '6xl': 9999,  // Completamente circular
}

Hooks Personalizados

TM Theme proporciona 4 hooks especializados para trabajar con el sistema de diseño:

1. useTheme

Propósito: Acceder al tema actual y sus funciones

Retorna:

{
  theme: ITheme,              // Tema completo actual
  brand: Brand,               // Marca actual ('bitcar' | 'tip' | 'ofs')
  mode: Mode,                 // Modo ('light' | 'dark')
  setBrand: (brand) => void,  // Cambiar marca
  setMode: (mode) => void,    // Cambiar modo
}

Ejemplo de Uso:

import { useTheme } from '@tipmexico/tm_theme';

function MyComponent() {
  const { theme, brand, setBrand } = useTheme();

  return (
    <View style={{ backgroundColor: theme.colors.primary }}>
      <Text>Marca actual: {brand}</Text>
      <Button onPress={() => setBrand('tip')}>
        Cambiar a TIP
      </Button>
    </View>
  );
}

2. useColor

Propósito: Obtener colores del tema de forma type-safe

Parámetros:

  • color: ColorType - Tipo de color a obtener

Retorna: string - Valor hexadecimal del color

Colores Disponibles:

  • Básicos: 'primary', 'black', 'white', 'transparent'
  • Estados: 'green', 'greenLight', 'red', 'redLight', 'blue', 'blueLight', 'yellow', 'yellowLight'
  • Grises: 'gray1' a 'gray8'
  • Acentos: 'accents1' a 'accents4'

Ejemplo de Uso:

import { useColor } from '@tipmexico/tm_theme';

function MyComponent() {
  const primaryColor = useColor('primary');
  const errorColor = useColor('red');
  const grayColor = useColor('gray5');

  return (
    <View>
      <Text style={{ color: primaryColor }}>Primary Text</Text>
      <Text style={{ color: errorColor }}>Error Message</Text>
      <View style={{ backgroundColor: grayColor }} />
    </View>
  );
}

3. useTypography

Propósito: Obtener tamaños de fuente del tema

Parámetros:

  • type: TypographyType - Tipo de tipografía

Retorna: number - Tamaño de fuente en puntos

Tipos Disponibles:

  • Heading: 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
  • Paragraph: 'xlarge', 'large', 'regular', 'small', 'xsmall'
  • Button: 'large', 'regular', 'small' (con prefijo button-)

Ejemplo de Uso:

import { useTypography } from '@tipmexico/tm_theme';

function MyComponent() {
  const h1Size = useTypography('h1');
  const bodySize = useTypography('regular');
  const captionSize = useTypography('small');

  return (
    <View>
      <Text style={{ fontSize: h1Size }}>Título</Text>
      <Text style={{ fontSize: bodySize }}>Contenido</Text>
      <Text style={{ fontSize: captionSize }}>Caption</Text>
    </View>
  );
}

4. useSearch

Propósito: Hook de búsqueda y filtrado reutilizable

Características:

  • Búsqueda en tiempo real
  • Debouncing integrado
  • Filtrado flexible
  • Type-safe

Ejemplo de Uso:

import { useSearch } from '@tipmexico/tm_theme';

function SearchableList({ items }) {
  const { searchTerm, setSearchTerm, filteredResults } = useSearch(
    items,
    (item, term) => item.name.toLowerCase().includes(term.toLowerCase())
  );

  return (
    <View>
      <TextField
        value={searchTerm}
        onChangeText={setSearchTerm}
        placeholder="Buscar..."
      />
      {filteredResults.map(item => (
        <Card key={item.id}>{item.name}</Card>
      ))}
    </View>
  );
}

5. useAppFonts

Propósito: Cargar fuentes específicas de la marca

Parámetros:

  • brand: Brand - Marca para cargar fuentes

Retorna: [boolean] - Array con estado de carga

Uso Interno: Este hook es usado automáticamente por el ThemeProvider, no necesitas usarlo directamente.


Providers

1. ThemeProvider

Propósito: Provider principal que envuelve la aplicación para habilitar tematización

Props:

{
  initialBrand?: 'bitcar' | 'tip' | 'ofs',  // Default: 'bitcar'
  initialMode?: 'light' | 'dark',            // Default: 'light'
  children: ReactNode
}

Ejemplo de Uso:

import { ThemeProvider } from '@tipmexico/tm_theme';

export default function App() {
  return (
    <ThemeProvider initialBrand="tip" initialMode="light">
      <YourApplication />
    </ThemeProvider>
  );
}

2. LoaderProvider

Propósito: Gestión global de estados de carga

Funcionalidades:

  • Mostrar/ocultar loader global
  • Loading states centralizados
  • Overlay de carga

Ejemplo de Uso:

import { LoaderProvider, useLoader } from '@tipmexico/tm_theme';

// En App.tsx
function App() {
  return (
    <ThemeProvider>
      <LoaderProvider>
        <YourApp />
      </LoaderProvider>
    </ThemeProvider>
  );
}

// En componente
function MyComponent() {
  const { showLoader, hideLoader } = useLoader();

  const handleAction = async () => {
    showLoader();
    await someAsyncAction();
    hideLoader();
  };
}

3. ModalProvider

Propósito: Gestión global de modales

Funcionalidades:

  • Abrir/cerrar modales desde cualquier parte
  • Stack de modales
  • Animaciones de entrada/salida

Ejemplo de Uso:

import { ModalProvider, useModal } from '@tipmexico/tm_theme';

// En App.tsx
function App() {
  return (
    <ThemeProvider>
      <ModalProvider>
        <YourApp />
      </ModalProvider>
    </ThemeProvider>
  );
}

// En componente
function MyComponent() {
  const { openModal, closeModal } = useModal();

  const handleOpenModal = () => {
    openModal({
      title: 'Confirmación',
      content: <Text>¿Estás seguro?</Text>,
      onConfirm: () => console.log('Confirmed'),
    });
  };
}

Instalación y Configuración

Instalación

Para Proyectos Expo Managed


# Con yarn
yarn add @tipmexico/tm_theme

# Para iOS (después de instalar)
npx pod-install

Dependencias Peer

Asegúrate de tener instaladas las siguientes dependencias:

# Dependencias requeridas
expo install react-native-svg
expo install react-native-gesture-handler
expo install expo-font

Configuración Básica

1. Envolver la Aplicación con ThemeProvider

// App.tsx
import React from 'react';
import { ThemeProvider } from '@tipmexico/tm_theme';
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
  return (
    <ThemeProvider initialBrand="bitcar" initialMode="light">
      <NavigationContainer>
        <YourAppNavigation />
      </NavigationContainer>
    </ThemeProvider>
  );
}

2. Configuración con Múltiples Providers

// App.tsx
import React from 'react';
import {
  ThemeProvider,
  LoaderProvider,
  ModalProvider
} from '@tipmexico/tm_theme';

export default function App() {
  return (
    <ThemeProvider initialBrand="tip">
      <LoaderProvider>
        <ModalProvider>
          <NavigationContainer>
            <YourAppNavigation />
          </NavigationContainer>
        </ModalProvider>
      </LoaderProvider>
    </ThemeProvider>
  );
}

3. Configuración TypeScript

Asegúrate de que tu tsconfig.json incluya:

{
  "compilerOptions": {
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "jsx": "react-native",
    "moduleResolution": "node"
  }
}

4. Configuración de SVG (React Native)

Si usas React Native sin Expo, configura el transformer de SVG:

metro.config.js:

const { getDefaultConfig } = require('expo/metro-config');

module.exports = (() => {
  const config = getDefaultConfig(__dirname);

  const { transformer, resolver } = config;

  config.transformer = {
    ...transformer,
    babelTransformerPath: require.resolve('react-native-svg-transformer'),
  };
  config.resolver = {
    ...resolver,
    assetExts: resolver.assetExts.filter((ext) => ext !== 'svg'),
    sourceExts: [...resolver.sourceExts, 'svg'],
  };

  return config;
})();

Verificación de Instalación

Para verificar que todo funciona correctamente:

// TestComponent.tsx
import React from 'react';
import { View } from 'react-native';
import {
  Button,
  TextField,
  Card,
  useTheme,
  useColor
} from '@tipmexico/tm_theme';

export function TestComponent() {
  const { theme, brand } = useTheme();
  const primaryColor = useColor('primary');

  return (
    <View style={{ flex: 1, padding: 16 }}>
      <Card>
        <TextField
          label="Test Input"
          placeholder="Escribe algo..."
        />
        <Button
          title="Test Button"
          onPress={() => console.log('Funciona!')}
        />
      </Card>
    </View>
  );
}

Ejemplos de Uso

Ejemplo 1: Formulario de Login

import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import {
  LoginTemplate,
  TextField,
  Button,
  Alert,
  useTheme,
  useColor,
} from '@tipmexico/tm_theme';

export function LoginScreen() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const { theme } = useTheme();
  const primaryColor = useColor('primary');

  const handleLogin = async () => {
    if (!email || !password) {
      setError('Por favor completa todos los campos');
      return;
    }
    // Lógica de login
  };

  return (
    <LoginTemplate logo={require('./assets/logo.png')}>
      <View style={styles.container}>
        {error && (
          <Alert
            type="error"
            message={error}
            onClose={() => setError('')}
          />
        )}

        <TextField
          label="Email"
          placeholder="[email protected]"
          value={email}
          onChangeText={setEmail}
          keyboardType="email-address"
          autoCapitalize="none"
        />

        <TextField
          label="Contraseña"
          placeholder="••••••••"
          value={password}
          onChangeText={setPassword}
          secureTextEntry
        />

        <Button
          title="Iniciar Sesión"
          onPress={handleLogin}
          fullWidth
          style={{ marginTop: theme.spacing.lg }}
        />
      </View>
    </LoginTemplate>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
    gap: 16,
  },
});

Ejemplo 2: Lista con Búsqueda y Filtros

import React from 'react';
import { View, FlatList, StyleSheet } from 'react-native';
import {
  TextField,
  Card,
  Badge,
  IconButton,
  Skeleton,
  useSearch,
  useTheme,
  IconSearch,
  IconFilter,
} from '@tipmexico/tm_theme';

interface Vehicle {
  id: string;
  name: string;
  plate: string;
  status: 'active' | 'maintenance' | 'inactive';
}

export function VehicleListScreen({ vehicles, loading }: Props) {
  const { theme } = useTheme();
  const { searchTerm, setSearchTerm, filteredResults } = useSearch(
    vehicles,
    (vehicle, term) =>
      vehicle.name.toLowerCase().includes(term.toLowerCase()) ||
      vehicle.plate.toLowerCase().includes(term.toLowerCase())
  );

  if (loading) {
    return (
      <View style={styles.container}>
        <Skeleton count={5} height={80} />
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <View style={styles.searchBar}>
        <TextField
          placeholder="Buscar vehículo..."
          value={searchTerm}
          onChangeText={setSearchTerm}
          leftIcon={<IconSearch size={20} />}
          style={{ flex: 1 }}
        />
        <IconButton
          icon={<IconFilter size={24} />}
          onPress={() => {/* Abrir filtros */}}
        />
      </View>

      <FlatList
        data={filteredResults}
        keyExtractor={(item) => item.id}
        renderItem={({ item }) => (
          <Card style={styles.card}>
            <View style={styles.cardContent}>
              <View>
                <Text style={styles.vehicleName}>{item.name}</Text>
                <Text style={styles.plate}>{item.plate}</Text>
              </View>
              <Badge
                label={item.status}
                variant={
                  item.status === 'active'
                    ? 'success'
                    : item.status === 'maintenance'
                    ? 'warning'
                    : 'error'
                }
              />
            </View>
          </Card>
        )}
        contentContainerStyle={{ gap: theme.spacing.md }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  searchBar: {
    flexDirection: 'row',
    gap: 8,
    marginBottom: 16,
  },
  card: {
    padding: 16,
  },
  cardContent: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  vehicleName: {
    fontSize: 16,
    fontWeight: '600',
  },
  plate: {
    fontSize: 14,
    color: '#6B7280',
  },
});

Ejemplo 3: Dashboard con Métricas

import React from 'react';
import { View, ScrollView, StyleSheet } from 'react-native';
import {
  Header,
  CardMetrics,
  CardTimeline,
  CardActions,
  useTheme,
  useColor,
  IconCar,
  IconMaintenance,
  IconMoney,
  IconUsers,
} from '@tipmexico/tm_theme';

export function DashboardScreen() {
  const { theme } = useTheme();
  const primaryColor = useColor('primary');

  const metrics = [
    {
      id: '1',
      title: 'Vehículos',
      value: '248',
      icon: <IconCar size={32} color={primaryColor} />,
      trend: '+12%'
    },
    {
      id: '2',
      title: 'Mantenimientos',
      value: '43',
      icon: <IconMaintenance size={32} color={primaryColor} />,
      trend: '+5%'
    },
    {
      id: '3',
      title: 'Gasto Mensual',
      value: '$45.2K',
      icon: <IconMoney size={32} color={primaryColor} />,
      trend: '-3%'
    },
    {
      id: '4',
      title: 'Operadores',
      value: '156',
      icon: <IconUsers size={32} color={primaryColor} />,
      trend: '+8%'
    },
  ];

  const recentActivities = [
    {
      id: '1',
      title: 'Mantenimiento programado',
      subtitle: 'Vehículo ABC-123',
      time: 'Hace 2 horas'
    },
    {
      id: '2',
      title: 'Nueva multa registrada',
      subtitle: 'Vehículo XYZ-789',
      time: 'Hace 4 horas'
    },
  ];

  return (
    <View style={styles.container}>
      <Header
        title="Dashboard"
        subtitle="Resumen de tu flota"
        showBack={false}
      />

      <ScrollView
        style={styles.content}
        contentContainerStyle={{ gap: theme.spacing.lg }}
      >
        {/* Métricas */}
        <View style={styles.metricsGrid}>
          {metrics.map((metric) => (
            <CardMetrics
              key={metric.id}
              title={metric.title}
              value={metric.value}
              icon={metric.icon}
              trend={metric.trend}
              style={styles.metricCard}
            />
          ))}
        </View>

        {/* Actividad Reciente */}
        <CardTimeline
          title="Actividad Reciente"
          items={recentActivities}
        />

        {/* Acciones Rápidas */}
        <CardActions
          title="Acciones Rápidas"
          actions={[
            {
              label: 'Programar Mantenimiento',
              onPress: () => {},
              icon: <IconCalendar />,
            },
            {
              label: 'Ver Reportes',
              onPress: () => {},
              icon: <IconReport />,
            },
          ]}
        />
      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  content: {
    flex: 1,
    padding: 16,
  },
  metricsGrid: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 12,
  },
  metricCard: {
    flex: 1,
    minWidth: '45%',
  },
});

Ejemplo 4: Modal de Confirmación

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import {
  Modal,
  ModalConfirmation,
  Button,
  Alert,
  useModal,
  useTheme,
} from '@tipmexico/tm_theme';

export function DeleteConfirmationExample() {
  const { openModal, closeModal } = useModal();
  const { theme } = useTheme();

  const handleDelete = () => {
    openModal(
      <ModalConfirmation
        title="¿Eliminar vehículo?"
        message="Esta acción no se puede deshacer. El vehículo será eliminado permanentemente."
        confirmLabel="Eliminar"
        cancelLabel="Cancelar"
        variant="danger"
        onConfirm={async () => {
          // Lógica de eliminación
          await deleteVehicle();
          closeModal();
          showSuccessAlert();
        }}
        onCancel={closeModal}
      />
    );
  };

  return (
    <View style={styles.container}>
      <Button
        title="Eliminar Vehículo"
        variant="danger"
        onPress={handleDelete}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
  },
});

Ejemplo 5: Formulario con Validación

import React, { useState } from 'react';
import { View, ScrollView, StyleSheet } from 'react-native';
import {
  Card,
  TextField,
  TextArea,
  Dropdown,
  DatePicker,
  TimePicker,
  Switch,
  Button,
  Alert,
  useTheme,
  useColor,
} from '@tipmexico/tm_theme';

export function MaintenanceFormScreen() {
  const { theme } = useTheme();
  const [formData, setFormData] = useState({
    vehicle: '',
    serviceType: '',
    provider: '',
    date: new Date(),
    time: '',
    notes: '',
    urgent: false,
  });
  const [errors, setErrors] = useState({});

  const validateForm = () => {
    const newErrors = {};
    if (!formData.vehicle) newErrors.vehicle = 'Selecciona un vehículo';
    if (!formData.serviceType) newErrors.serviceType = 'Selecciona un servicio';
    if (!formData.provider) newErrors.provider = 'Selecciona un proveedor';

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const handleSubmit = async () => {
    if (!validateForm()) {
      return;
    }

    try {
      // Lógica de envío
      await submitMaintenance(formData);
      // Mostrar éxito
    } catch (error) {
      // Mostrar error
    }
  };

  return (
    <ScrollView style={styles.container}>
      <Card>
        <View style={styles.form}>
          <Dropdown
            label="Vehículo"
            placeholder="Selecciona un vehículo"
            value={formData.vehicle}
            onValueChange={(value) =>
              setFormData({ ...formData, vehicle: value })
            }
            options={[
              { label: 'ABC-123', value: '1' },
              { label: 'XYZ-789', value: '2' },
            ]}
            error={errors.vehicle}
          />

          <Dropdown
            label="Tipo de Servicio"
            placeholder="Selecciona un servicio"
            value={formData.serviceType}
            onValueChange={(value) =>
              setFormData({ ...formData, serviceType: value })
            }
            options={[
              { label: 'Mantenimiento Preventivo', value: 'preventive' },
              { label: 'Reparación', value: 'repair' },
            ]}
            error={errors.serviceType}
          />

          <Dropdown
            label="Proveedor"
            placeholder="Selecciona un proveedor"
            value={formData.provider}
            onValueChange={(value) =>
              setFormData({ ...formData, provider: value })
            }
            options={[
              { label: 'Taller ABC', value: '1' },
              { label: 'Servicio XYZ', value: '2' },
            ]}
            error={errors.provider}
          />

          <DatePicker
            label="Fecha"
            value={formData.date}
            onChange={(date) =>
              setFormData({ ...formData, date })
            }
          />

          <TimePicker
            label="Hora"
            value={formData.time}
            onChange={(time) =>
              setFormData({ ...formData, time })
            }
          />

          <TextArea
            label="Notas"
            placeholder="Detalles adicionales..."
            value={formData.notes}
            onChangeText={(notes) =>
              setFormData({ ...formData, notes })
            }
            maxLength={500}
          />

          <View style={styles.switchContainer}>
            <Text>Urgente</Text>
            <Switch
              value={formData.urgent}
              onValueChange={(urgent) =>
                setFormData({ ...formData, urgent })
              }
            />
          </View>

          <Button
            title="Programar Mantenimiento"
            onPress={handleSubmit}
            fullWidth
            style={{ marginTop: theme.spacing.lg }}
          />
        </View>
      </Card>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  form: {
    gap: 16,
    padding: 16,
  },
  switchContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingVertical: 8,
  },
});

Ejemplo 6: Tabla con Paginación

import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import {
  TableStriped,
  Pagination,
  Badge,
  IconButton,
  useTheme,
  IconEdit,
  IconTrash,
} from '@tipmexico/tm_theme';

export function VehicleTableScreen({ data }: Props) {
  const { theme } = useTheme();
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 10;

  const columns = [
    { key: 'plate', header: 'Placa', width: '15%' },
    { key: 'model', header: 'Modelo', width: '25%' },
    { key: 'year', header: 'Año', width: '10%' },
    {
      key: 'status',
      header: 'Estado',
      width: '15%',
      render: (value) => (
        <Badge
          label={value}
          variant={value === 'Activo' ? 'success' : 'error'}
        />
      ),
    },
    {
      key: 'actions',
      header: 'Acciones',
      width: '15%',
      render: (_, row) => (
        <View style={styles.actions}>
          <IconButton
            icon={<IconEdit size={20} />}
            onPress={() => handleEdit(row)}
          />
          <IconButton
            icon={<IconTrash size={20} />}
            onPress={() => handleDelete(row)}
          />
        </View>
      ),
    },
  ];

  const paginatedData = data.slice(
    (currentPage - 1) * itemsPerPage,
    currentPage * itemsPerPage
  );

  return (
    <View style={styles.container}>
      <TableStriped
        columns={columns}
        data={paginatedData}
      />

      <Pagination
        currentPage={currentPage}
        totalPages={Math.ceil(data.length / itemsPerPage)}
        onPageChange={setCurrentPage}
        style={{ marginTop: theme.spacing.lg }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  actions: {
    flexDirection: 'row',
    gap: 8,
  },
});

Storybook - Documentación Interactiva

TM Theme incluye Storybook con documentación completa de todos los componentes.

Ejecutar Storybook

# Iniciar Storybook en modo desarrollo
yarn storybook

# Abrir en navegador
# http://localhost:6006

Construir Storybook para Producción

# Generar build estático
yarn build-storybook

# Resultado en ./storybook-static

Características de Storybook

Coverage Completo:

  • ✅ 27 Atoms documentados
  • ✅ 14 Molecules documentados
  • ✅ 5 Organisms documentados
  • ✅ 1 Template documentado
  • ✅ 2 Providers documentados
  • ✅ Sistema de colores
  • ✅ Tipografía

Funcionalidades:

  • Playground Interactivo - Prueba props en tiempo real
  • Controls - Modifica propiedades dinámicamente
  • Docs - Documentación auto-generada
  • Viewport - Prueba en diferentes tamaños
  • Accessibility - Validación de accesibilidad

Ejemplo de Story:

// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

const meta: Meta<typeof Button> = {
  title: 'Atoms/Button',
  component: Button,
  parameters: {
    docs: {
      description: {
        component: 'Botón versátil con múltiples variantes y tamaños',
      },
    },
  },
  argTypes: {
    variant: {
      control: 'select',
      options: ['primary', 'secondary', 'outline', 'ghost'],
    },
    size: {
      control: 'select',
      options: ['small', 'medium', 'large'],
    },
  },
};

export default meta;
type Story = StoryObj<typeof Button>;

export const Primary: Story = {
  args: {
    title: 'Primary Button',
    variant: 'primary',
  },
};

export const Secondary: Story = {
  args: {
    title: 'Secondary Button',
    variant: 'secondary',
  },
};

Mejores Prácticas

1. Uso de Componentes

✅ Recomendado:

// Usa componentes del sistema siempre que sea posible
import { Button, TextField } from '@tipmexico/tm_theme';

// Usa hooks para acceder a theme tokens
const primaryColor = useColor('primary');
const h1Size = useTypography('h1');

❌ Evitar:

// No uses valores hardcodeados
<Text style={{ color: '#FF5733', fontSize: 18 }}>Title</Text>

// Usa en su lugar:
const primaryColor = useColor('primary');
const h1Size = useTypography('h1');
<Text style={{ color: primaryColor, fontSize: h1Size }}>Title</Text>

2. Espaciado Consistente

✅ Recomendado:

const { theme } = useTheme();

<View style={{
  padding: theme.spacing.md,
  gap: theme.spacing.sm,
  marginBottom: theme.spacing.lg,
}} />

❌ Evitar:

// Valores arbitrarios
<View style={{ padding: 13, gap: 7, marginBottom: 23 }} />

3. Colores Semánticos

✅ Recomendado:

// Usa colores semánticos
const successColor = useColor('green');
const errorColor = useColor('red');
const warningColor = useColor('yellow');

❌ Evitar:

// Colores hardcodeados sin significado
const color1 = '#10B981';
const color2 = '#EF4444';

4. Tipografía Escalable

✅ Recomendado:

// Usa la escala tipográfica
const titleSize = useTypography('h2');
const bodySize = useTypography('regular');
const captionSize = useTypography('small');

❌ Evitar:

// Tamaños arbitrarios
<Text style={{ fontSize: 23 }}>Title</Text>
<Text style={{ fontSize: 15 }}>Body</Text>

5. Responsive Design

✅ Recomendado:

import { isWeb, isIOS, isAndroid } from '@tipmexico/tm_theme';

// Adapta según plataforma
const spacing = isWeb ? theme.spacing.xl : theme.spacing.md;

6. Composición de Componentes

✅ Recomendado:

// Compone componentes para crear UIs complejas
<Card>
  <CardTitle title="Vehículo" subtitle="ABC-123" />
  <Divisor />
  <CardMetrics value="1,234 km" label="Kilometraje" />
  <CardActions
    actions={[
      { label: 'Editar', onPress: handleEdit },
      { label: 'Eliminar', onPress: handleDelete },
    ]}
  />
</Card>

7. Accesibilidad

✅ Recomendado:

// Siempre proporciona labels y hints
<TextField
  label="Email"
  placeholder="[email protected]"
  accessibilityLabel="Campo de email"
  accessibilityHint="Ingresa tu correo electrónico"
/>

<Button
  title="Enviar"
  accessibilityLabel="Enviar formulario"
  accessibilityRole="button"
/>

8. Manejo de Estados

✅ Recomendado:

// Muestra estados de carga y error
function MyComponent() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  if (loading) return <Spinner />;
  if (error) return <Alert type="error" message={error} />;

  return <Content />;
}

9. Performance

✅ Recomendado:

// Usa React.memo para componentes puros
import React, { memo } from 'react';

export const VehicleCard = memo(({ vehicle }) => {
  return <Card>{/* ... */}</Card>;
});

// Usa useMemo para cálculos costosos
const filteredVehicles = useMemo(
  () => vehicles.filter(v => v.status === 'active'),
  [vehicles]
);

10. Testing

✅ Recomendado:

// Testea componentes con testing-library
import { render, fireEvent } from '@testing-library/react-native';
import { Button, ThemeProvider } from '@tipmexico/tm_theme';

test('button calls onPress when clicked', () => {
  const onPress = jest.fn();
  const { getByText } = render(
    <ThemeProvider>
      <Button title="Click me" onPress={onPress} />
    </ThemeProvider>
  );

  fireEvent.press(getByText('Click me'));
  expect(onPress).toHaveBeenCalled();
});

Utilidades

1. Platform Helpers

import { isWeb, isIOS, isAndroid, isMobile } from '@tipmexico/tm_theme';

// Renderizado condicional por plataforma
{isWeb && <WebOnlyComponent />}
{isMobile && <MobileOnlyComponent />}
{isIOS && <IOSSpecificComponent />}

2. Dimension Helpers

import {
  screenWidth,
  screenHeight,
  wp, // width percentage
  hp, // height percentage
} from '@tipmexico/tm_theme';

// Uso
const cardWidth = wp(90); // 90% del ancho de pantalla
const headerHeight = hp(10); // 10% del alto de pantalla

3. Component Helpers

Utilidades para trabajar con componentes:

import { getTestID, getAccessibilityProps } from '@tipmexico/tm_theme';

// Auto-generar props de accesibilidad
<Button {...getAccessibilityProps('submit-button', 'button')} />

Guía de Contribución

Agregar un Nuevo Componente

1. Crear estructura de archivos

src/components/atoms/my-component/
├── MyComponent.tsx          # Componente
├── MyComponent.types.ts     # TypeScript interfaces
├── MyComponent.styles.ts    # Estilos (si aplica)
├── index.ts                 # Barrel export

2. Implementar componente

// MyComponent.tsx
import React from 'react';
import { View, Text } from 'react-native';
import { useTheme, useColor } from '../../../hooks';
import { MyComponentProps } from './MyComponent.types';

export const MyComponent: React.FC<MyComponentProps> = ({
  title,
  variant = 'default',
  ...props
}) => {
  const { theme } = useTheme();
  const primaryColor = useColor('primary');

  return (
    <View style={{ padding: theme.spacing.md }}>
      <Text style={{ color: primaryColor }}>{title}</Text>
    </View>
  );
};

3. Definir tipos

// MyComponent.types.ts
export interface MyComponentProps {
  title: string;
  variant?: 'default' | 'primary' | 'secondary';
  onPress?: () => void;
}

4. Crear Story

// stories/components/atoms/MyComponent.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { MyComponent } from '../../../components/atoms/my-component';

const meta: Meta<typeof MyComponent> = {
  title: 'Atoms/MyComponent',
  component: MyComponent,
};

export default meta;
type Story = StoryObj<typeof MyComponent>;

export const Default: Story = {
  args: {
    title: 'My Component',
    variant: 'default',
  },
};

5. Exportar

// src/components/atoms/index.ts
export * from './my-component';

Standards de Código

TypeScript:

  • Usar tipos explícitos
  • Evitar any
  • Definir interfaces para props

Naming:

  • PascalCase para componentes
  • camelCase para funciones y variables
  • UPPER_CASE para constantes

Styling:

  • Usar hooks de tema (useTheme, useColor, useTypography)
  • No usar valores hardcodeados
  • Preferir StyleSheet.create()

Testing:

  • Unit tests con Jest
  • Component tests con Testing Library
  • Coverage mínimo: 80%

Arquitectura Técnica

Estructura de Directorios

src/
├── assets/              # Assets estáticos
│   ├── CarDefault.tsx
│   ├── ErrorConnection.tsx
│   ├── ErrorEmpty.tsx
│   └── ErrorNotFound.tsx
│
├── components/          # Componentes UI
│   ├── atoms/          # 27 componentes básicos
│   ├── molecules/      # 14 componentes compuestos
│   ├── organisms/      # 5 componentes complejos
│   └── templates/      # 1 plantilla
│
├── constants/          # Constantes globales
│   └── globals.constants.ts
│
├── hooks/              # Custom hooks
│   ├── useAppFonts.ts
│   ├── useColor.ts
│   ├── useTypography.ts
│   └── useSearch.ts
│
├── icons/              # 60+ iconos SVG
│   ├── IconCar.tsx
│   ├── IconHome.tsx
│   └── ...
│
├── interfaces/         # TypeScript interfaces
│   ├── colors.interface.ts
│   ├── typography.interface.ts
│   ├── theme.interface.ts
│   └── icons.interface.ts
│
├── providers/          # Context providers
│   ├── loader/
│   └── modal/
│
├── theme/              # Sistema de temas
│   ├── brands/
│   │   ├── bitcar/
│   │   │   └── light.ts
│   │   ├── tip/
│   │   │   └── light.ts
│   │   └── ofs/
│   │       └── light.ts
│   └── ThemeContext.tsx
│
├── types/              # TypeScript types
│   ├── colors.type.ts
│   ├── components.type.ts
│   ├── icons.type.ts
│   ├── scales.type.ts
│   ├── sizes.type.ts
│   ├── theme.type.ts
│   └── typography.type.ts
│
├── utils/              # Utilidades
│   ├── components.ts
│   ├── dimensions.ts
│   └── platform.ts
│
└── index.ts            # Entry point

Tecnologías y Dependencias

Core Dependencies

| Tecnología | Versión | Uso | | ---------------- | ------- | --------------- | | React | 19.0.0 | Framework UI | | React Native | 0.79.5 | Framework móvil | | TypeScript | 5.x | Type safety | | Expo | 53.0.19 | Toolchain |

UI Dependencies

| Dependencia | Versión | Uso | | --------------------------- | -------- | ------------------------ | | React Native SVG | 15.11.2 | Iconos vectoriales | | Expo Linear Gradient | 14.1.5 | Gradientes | | React Native Calendars | 1.1312.0 | Componente de calendario | | React Native Pager View | 6.9.1 | Swipeable views | | RN UI DatePicker | 3.1.2 | Selector de fecha |

Fuentes

| Fuente | Uso | | ----------- | ----------------- | | Poppins | Headings, títulos | | Roboto | Párrafos, UI text |

Dev Dependencies

| Herramienta | Versión | Uso | | ------------- | ------- | --------------- | | Storybook | 9.0.13 | Documentación | | Vitest | 3.0.9 | Testing | | ESLint | 9.24.0 | Linting | | Prettier | 3.5.3 | Formateo código | | Husky | 9.1.7 | Git hooks |


Build y Deploy

Build para Producción

# Limpiar build anterior
yarn clean

# Compilar TypeScript
yarn build

# Resultado en ./build/

Publicar a NPM

# Incrementar versión
npm version patch|minor|major

# Publicar
npm publish --access public

Configuración de Package

El módulo se publica como scoped package bajo @tipmexico:

{
  "name": "@tipmexico/tm_theme",
  "version": "1.2.34",
  "main": "build/index.js",
  "types": "build/index.d.ts"
}

Troubleshooting

Problema: Fuentes no se cargan

Solución:

// Asegúrate de que ThemeProvider esté correctamente implementado
import { ThemeProvider } from '@tipmexico/tm_theme';

export default function App() {
  return (
    <ThemeProvider initialBrand="bitcar">
      <YourApp />
    </ThemeProvider>
  );
}

Problema: Storybook no inicia

Solución:

# Limpiar caché
rm -rf node_modules/.cache

# Reinstalar
yarn install

# Reintentar
yarn storybook

¿Cómo contribuyo al proyecto?

  1. Fork del repositorio
  2. Crear feature branch
  3. Implementar cambios con tests
  4. Crear Pull Request
  5. Code review por el equipo

Soporte y Contacto

Repositorio

Bitbucket - tm_theme


Issue Tracker

Reportar Issues


Documentación Adicional


Glosario

Atomic Design: Metodología de diseño que organiza componentes en 5 niveles: átomos, moléculas, organismos, templates y páginas.

Design System: Colección de componentes reutilizables y guías de estilo para crear interfaces consistentes.

Design Tokens: Valores atómicos de diseño (colores, espaciado, tipografía) que definen el lenguaje visual.

Theme: Conjunto de tokens de diseño que define la apariencia visual de una aplicación.

Brand: Marca o submarca con su propia identidad visual y tema personalizado.

Component: Pieza reutilizable de UI con comportamiento y estilo encapsulado.

Hook: Función de React que permite usar características como estado y contexto.

Storybook: Herramienta para desarrollar y documentar componentes UI de forma aislada.

Type Safety: Verificación de tipos en tiempo de compilación con TypeScript.

Peer Dependency: Dependencia que debe ser instalada por el consumidor del paquete.


Changelog

v1.2.34 (Actual - Noviembre 2025)

Agregado:

  • 27 componentes Atoms completos
  • 14 componentes Molecules
  • 5 componentes Organisms
  • Sistema de tematización multi-marca
  • 60+ iconos SVG optimizados
  • Storybook con documentación completa
  • 4 hooks personalizados
  • Design tokens completos
  • Soporte TypeScript completo

Mejorado:

  • Performance de renderizado
  • Type safety
  • Documentación

Corregido:

  • Bugs de espaciado
  • Issues de accesibilidad
  • Problemas de tipado

v1.2.x

  • Implementación de componentes base
  • Setup de arquitectura Atomic Design
  • Integración con Expo 53
  • Soporte multi-plataforma

v1.1.x

  • Versión inicial
  • Componentes básicos
  • Sistema de temas básico

Actualización

Última actualización: Noviembre 2025
Versión de documentación: 1.0
Mantenedor: Cristian Bedoya
Estado: ✅ Producción - Activamente mantenido