60 lines
1.3 KiB
TypeScript
60 lines
1.3 KiB
TypeScript
import { type ClassValue, clsx } from 'clsx';
|
|
import { twMerge } from 'tailwind-merge';
|
|
|
|
/**
|
|
* Merge Tailwind CSS classes with proper precedence
|
|
*/
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
/**
|
|
* Format a date to a human-readable string
|
|
*/
|
|
export function formatDate(date: Date | string, options?: Intl.DateTimeFormatOptions): string {
|
|
const d = typeof date === 'string' ? new Date(date) : date;
|
|
return d.toLocaleDateString('en-US', {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
...options
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Format currency amount
|
|
*/
|
|
export function formatCurrency(amount: number, currency = 'EUR'): string {
|
|
return new Intl.NumberFormat('en-US', {
|
|
style: 'currency',
|
|
currency
|
|
}).format(amount);
|
|
}
|
|
|
|
/**
|
|
* Generate a random ID
|
|
*/
|
|
export function generateId(prefix = ''): string {
|
|
const id = Math.random().toString(36).substring(2, 9);
|
|
return prefix ? `${prefix}_${id}` : id;
|
|
}
|
|
|
|
/**
|
|
* Debounce a function
|
|
*/
|
|
export function debounce<T extends (...args: unknown[]) => unknown>(
|
|
fn: T,
|
|
delay: number
|
|
): (...args: Parameters<T>) => void {
|
|
let timeoutId: ReturnType<typeof setTimeout>;
|
|
return (...args: Parameters<T>) => {
|
|
clearTimeout(timeoutId);
|
|
timeoutId = setTimeout(() => fn(...args), delay);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Check if running in browser
|
|
*/
|
|
export const isBrowser = typeof window !== 'undefined';
|