🔧 Utilities Guide

Index

  1. Available Functions
  2. Formatting
  3. Haptic Feedback
  4. General Utilities
  5. Validation
  6. Adding New Utilities

Available Functions

Location: utils/helpers.ts

FunctionDescriptionExample
formatDateFormats relative date"2m ago", "5h ago"
formatRelativeTimeCompact relative time"5m", "2h", "3d"
formatTimeFormatted time"10:30 AM"
formatCurrencyFormatted currency"$1,234.56"
formatNumberAbbreviated numbers"1.2K", "3.5M"
truncateTextTruncate long text"Very long te..."
triggerHapticHaptic feedback-
generateIdGenerate unique ID"k7b3x9m2..."
debounceFunction debounce-
clampClamp number to rangeclamp(15, 0, 10) → 10

Formatting

formatDate

Converts a date to readable relative text.

import { formatDate } from '@/utils/helpers';

formatDate('2024-01-22T14:30:00Z');
// Resultados posibles:
// "Just now"     - Menos de 1 minuto
// "5m ago"       - Minutos
// "2h ago"       - Horas
// "3d ago"       - Días (menos de 7)
// "Jan 15"       - Más de 7 días

Typical usage:

<Text>{formatDate(item.createdAt)}</Text>
<Text>Creado {formatDate(notification.timestamp)}</Text>

formatRelativeTime

Versión más compacta del tiempo relativo.

import { formatRelativeTime } from '@/utils/helpers';

formatRelativeTime('2024-01-22T14:30:00Z');
// "just now"  - Menos de 60 segundos
// "5m"        - Minutos
// "2h"        - Horas
// "3d"        - Días
// "2w"        - Semanas (menos de 4)
// "Jan 15"    - Más de 4 semanas

Typical usage:

// En listas de mensajes o actividad
<Text style={styles.timestamp}>{formatRelativeTime(message.createdAt)}</Text>

formatTime

Formatea solo la hora de una fecha.

import { formatTime } from '@/utils/helpers';

formatTime('2024-01-22T14:30:00Z');
// "2:30 PM"

formatTime('2024-01-22T09:15:00Z');
// "9:15 AM"

Typical usage:

// En mensajes de chat
<Text>{formatTime(message.createdAt)}</Text>

formatCurrency

Formatea números como moneda.

import { formatCurrency } from '@/utils/helpers';

formatCurrency(1234.56);           // "$1,234.56"
formatCurrency(1234.56, 'EUR');    // "€1,234.56"
formatCurrency(99.99, 'MXN');      // "MX$99.99"

Parámetros:

  • amount: number - Cantidad a formatear
  • currency?: string - Código de moneda (default: 'USD')

Typical usage:

<Text style={styles.price}>{formatCurrency(product.price)}</Text>

formatNumber

Abrevia números grandes.

import { formatNumber } from '@/utils/helpers';

formatNumber(500);        // "500"
formatNumber(1500);       // "1.5K"
formatNumber(25000);      // "25.0K"
formatNumber(1500000);    // "1.5M"
formatNumber(2500000000); // "2500.0M"

Typical usage:

<Text>{formatNumber(user.followers)} seguidores</Text>
<Text>{formatNumber(item.views)} vistas</Text>

truncateText

Trunca texto largo con elipsis.

import { truncateText } from '@/utils/helpers';

truncateText('Este es un texto muy largo', 15);
// "Este es un t..."

truncateText('Corto', 15);
// "Corto"

Parámetros:

  • text: string - Texto a truncar
  • maxLength: number - Longitud máxima incluyendo elipsis

Typical usage:

<Text>{truncateText(item.description, 100)}</Text>

Haptic Feedback

triggerHaptic

Genera feedback táctil en el dispositivo.

import { triggerHaptic } from '@/utils/helpers';

// Tipos disponibles
await triggerHaptic('light');    // Tap suave
await triggerHaptic('medium');   // Tap medio
await triggerHaptic('heavy');    // Tap fuerte
await triggerHaptic('success');  // Notificación éxito
await triggerHaptic('warning');  // Notificación advertencia
await triggerHaptic('error');    // Notificación error

Cuándo usar cada tipo:

TipoUso recomendado
lightSelección de item, toggle pequeño
mediumBotones, acciones secundarias
heavyAcciones importantes, confirmaciones
successOperación completada correctamente
warningAlertas, acciones que requieren atención
errorErrores, operaciones fallidas

Ejemplos de uso:

// En un botón
const handlePress = () => {
  triggerHaptic('medium');
  onPress();
};

// En toggle de favorito
const handleFavorite = () => {
  triggerHaptic('light');
  toggleFavorite(item.id);
};

// En operación exitosa
const handleSave = async () => {
  try {
    await saveData();
    triggerHaptic('success');
    showToast('Guardado!', 'success');
  } catch {
    triggerHaptic('error');
    showToast('Error al guardar', 'error');
  }
};

Utilidades Generales

generateId

Genera un ID único.

import { generateId } from '@/utils/helpers';

const id = generateId();
// "k7b3x9m2lw4n8p1q"

Typical usage:

const newItem = {
  id: generateId(),
  title: 'Nuevo Item',
  createdAt: new Date().toISOString(),
};

debounce

Crea una versión debounced de una función.

import { debounce } from '@/utils/helpers';

// Crear función debounced
const debouncedSearch = debounce((query: string) => {
  searchAPI(query);
}, 300);

// Cada llamada reinicia el timer
debouncedSearch('h');     // No ejecuta
debouncedSearch('ho');    // No ejecuta
debouncedSearch('hol');   // No ejecuta
debouncedSearch('hola');  // Ejecuta después de 300ms

Parámetros:

  • func: Function - Función a ejecutar
  • wait: number - Tiempo de espera en ms

Typical usage:

// En un componente de búsqueda
const debouncedSearch = useCallback(
  debounce((text: string) => {
    performSearch(text);
  }, 300),
  []
);

<Input
  value={search}
  onChangeText={(text) => {
    setSearch(text);
    debouncedSearch(text);
  }}
/>

clamp

Limita un número dentro de un rango.

import { clamp } from '@/utils/helpers';

clamp(5, 0, 10);   // 5  (dentro del rango)
clamp(-5, 0, 10);  // 0  (por debajo del mínimo)
clamp(15, 0, 10);  // 10 (por encima del máximo)

Parámetros:

  • value: number - Valor a limitar
  • min: number - Valor mínimo
  • max: number - Valor máximo

Typical usage:

// Limitar progreso entre 0 y 100
const progress = clamp(rawProgress, 0, 100);

// Limitar scroll
const scrollY = clamp(currentScroll, 0, maxScroll);

Validación

Funciones de Validación Recomendadas

// utils/validation.ts

export function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

export function isValidUrl(url: string): boolean {
  try {
    new URL(url);
    return true;
  } catch {
    return false;
  }
}

export function isValidPhone(phone: string): boolean {
  const phoneRegex = /^\+?[\d\s-]{10,}$/;
  return phoneRegex.test(phone);
}

export function isNotEmpty(value: string): boolean {
  return value.trim().length > 0;
}

export function hasMinLength(value: string, min: number): boolean {
  return value.length >= min;
}

export function hasMaxLength(value: string, max: number): boolean {
  return value.length <= max;
}

// Uso
const errors: Record<string, string> = {};

if (!isValidEmail(email)) {
  errors.email = 'Email inválido';
}

if (!hasMinLength(password, 8)) {
  errors.password = 'Mínimo 8 caracteres';
}

Agregando Nuevas Utilidades

Plantilla

// utils/helpers.ts

/**
 * Descripción de lo que hace la función
 * @param param1 - Descripción del parámetro
 * @param param2 - Descripción del parámetro
 * @returns Descripción del valor retornado
 * @example
 * myFunction('test', 123) // resultado esperado
 */
export function myFunction(param1: string, param2: number): ReturnType {
  // Implementación
  return result;
}

Ejemplo: Función de Capitalización

/**
 * Capitaliza la primera letra de cada palabra
 * @param text - Texto a capitalizar
 * @returns Texto con cada palabra capitalizada
 * @example
 * capitalizeWords('hello world') // "Hello World"
 */
export function capitalizeWords(text: string): string {
  return text
    .toLowerCase()
    .split(' ')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
}

Ejemplo: Función de Ordenamiento

/**
 * Ordena un array por una propiedad
 * @param items - Array a ordenar
 * @param key - Propiedad por la cual ordenar
 * @param order - 'asc' o 'desc'
 * @returns Array ordenado
 */
export function sortBy<T>(
  items: T[],
  key: keyof T,
  order: 'asc' | 'desc' = 'asc'
): T[] {
  return [...items].sort((a, b) => {
    const aVal = a[key];
    const bVal = b[key];
    
    if (aVal < bVal) return order === 'asc' ? -1 : 1;
    if (aVal > bVal) return order === 'asc' ? 1 : -1;
    return 0;
  });
}

// Uso
const sortedItems = sortBy(items, 'createdAt', 'desc');

Checklist para Nuevas Utilidades

  • Función pura (sin efectos secundarios cuando sea posible)
  • Tipos TypeScript definidos
  • Documentación JSDoc
  • Ejemplos de uso
  • Manejo de casos edge
  • Tests unitarios (si aplica)