🔧 Utilities Guide
Index
Available Functions
Location: utils/helpers.ts
| Function | Description | Example |
|---|---|---|
formatDate | Formats relative date | "2m ago", "5h ago" |
formatRelativeTime | Compact relative time | "5m", "2h", "3d" |
formatTime | Formatted time | "10:30 AM" |
formatCurrency | Formatted currency | "$1,234.56" |
formatNumber | Abbreviated numbers | "1.2K", "3.5M" |
truncateText | Truncate long text | "Very long te..." |
triggerHaptic | Haptic feedback | - |
generateId | Generate unique ID | "k7b3x9m2..." |
debounce | Function debounce | - |
clamp | Clamp number to range | clamp(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 formatearcurrency?: 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 truncarmaxLength: 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:
| Tipo | Uso recomendado |
|---|---|
light | Selección de item, toggle pequeño |
medium | Botones, acciones secundarias |
heavy | Acciones importantes, confirmaciones |
success | Operación completada correctamente |
warning | Alertas, acciones que requieren atención |
error | Errores, 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 ejecutarwait: 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 limitarmin: number- Valor mínimomax: 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)