67 lines
1.7 KiB
TypeScript
67 lines
1.7 KiB
TypeScript
import { clsx } from 'clsx';
|
|
import { twMerge } from 'tailwind-merge';
|
|
|
|
type ClassValue = string | number | null | undefined | boolean | ClassValue[] | { [key: string]: any };
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
export function formatNumber(num: number): string {
|
|
if (num >= 1000000) {
|
|
return (num / 1000000).toFixed(1) + 'M';
|
|
}
|
|
if (num >= 1000) {
|
|
return (num / 1000).toFixed(1) + 'K';
|
|
}
|
|
return num.toString();
|
|
}
|
|
|
|
export function formatDate(date: Date | string): string {
|
|
const d = new Date(date);
|
|
return d.toLocaleDateString('en-US', {
|
|
year: 'numeric',
|
|
month: 'short',
|
|
day: 'numeric',
|
|
});
|
|
}
|
|
|
|
export function formatDateTime(date: Date | string): string {
|
|
const d = new Date(date);
|
|
return d.toLocaleDateString('en-US', {
|
|
year: 'numeric',
|
|
month: 'short',
|
|
day: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
});
|
|
}
|
|
|
|
export function calculateContrast(hex1: string, hex2: string): number {
|
|
// Convert hex to RGB
|
|
const getRGB = (hex: string) => {
|
|
const r = parseInt(hex.slice(1, 3), 16);
|
|
const g = parseInt(hex.slice(3, 5), 16);
|
|
const b = parseInt(hex.slice(5, 7), 16);
|
|
return [r, g, b];
|
|
};
|
|
|
|
// Calculate relative luminance
|
|
const getLuminance = (rgb: number[]) => {
|
|
const [r, g, b] = rgb.map(c => {
|
|
c = c / 255;
|
|
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
});
|
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
};
|
|
|
|
const rgb1 = getRGB(hex1);
|
|
const rgb2 = getRGB(hex2);
|
|
const lum1 = getLuminance(rgb1);
|
|
const lum2 = getLuminance(rgb2);
|
|
|
|
const brightest = Math.max(lum1, lum2);
|
|
const darkest = Math.min(lum1, lum2);
|
|
|
|
return (brightest + 0.05) / (darkest + 0.05);
|
|
} |