@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
1 lines • 27 kB
Source Map (JSON)
{"version":3,"file":"format.cjs","sources":["../../../src/utils/format.ts"],"sourcesContent":["import type {XID} from '../types';\n\n// Date formatting utilities\nexport const formatDate = (\n date: Date | string | number,\n options: Intl.DateTimeFormatOptions = {},\n locale = 'en'\n): string => {\n try {\n const dateObj = typeof date === 'string' || typeof date === 'number'\n ? new Date(date)\n : date;\n\n if (isNaN(dateObj.getTime())) {\n return 'Invalid Date';\n }\n\n const defaultOptions: Intl.DateTimeFormatOptions = {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n ...options,\n };\n\n return new Intl.DateTimeFormat(locale, defaultOptions).format(dateObj);\n } catch {\n return 'Invalid Date';\n }\n};\n\nexport const formatDateTime = (\n date: Date | string | number,\n options: Intl.DateTimeFormatOptions = {},\n locale = 'en'\n): string => {\n const defaultOptions: Intl.DateTimeFormatOptions = {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n ...options,\n };\n\n return formatDate(date, defaultOptions, locale);\n};\n\nexport const formatTime = (\n date: Date | string | number,\n options: Intl.DateTimeFormatOptions = {},\n locale = 'en'\n): string => {\n const defaultOptions: Intl.DateTimeFormatOptions = {\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n hour12: true,\n ...options,\n };\n\n return formatDate(date, defaultOptions, locale);\n};\n\nexport const formatRelativeTime = (\n date: Date | string | number,\n locale = 'en'\n): string => {\n try {\n const dateObj = typeof date === 'string' || typeof date === 'number'\n ? new Date(date)\n : date;\n\n if (isNaN(dateObj.getTime())) {\n return 'Invalid Date';\n }\n\n const now = new Date();\n const diffInSeconds = Math.floor((now.getTime() - dateObj.getTime()) / 1000);\n\n if (diffInSeconds < 60) {\n return 'just now';\n }\n\n const diffInMinutes = Math.floor(diffInSeconds / 60);\n if (diffInMinutes < 60) {\n return `${diffInMinutes} minute${diffInMinutes === 1 ? '' : 's'} ago`;\n }\n\n const diffInHours = Math.floor(diffInMinutes / 60);\n if (diffInHours < 24) {\n return `${diffInHours} hour${diffInHours === 1 ? '' : 's'} ago`;\n }\n\n const diffInDays = Math.floor(diffInHours / 24);\n if (diffInDays < 7) {\n return `${diffInDays} day${diffInDays === 1 ? '' : 's'} ago`;\n }\n\n const diffInWeeks = Math.floor(diffInDays / 7);\n if (diffInWeeks < 4) {\n return `${diffInWeeks} week${diffInWeeks === 1 ? '' : 's'} ago`;\n }\n\n const diffInMonths = Math.floor(diffInDays / 30);\n if (diffInMonths < 12) {\n return `${diffInMonths} month${diffInMonths === 1 ? '' : 's'} ago`;\n }\n\n const diffInYears = Math.floor(diffInDays / 365);\n return `${diffInYears} year${diffInYears === 1 ? '' : 's'} ago`;\n } catch {\n return 'Invalid Date';\n }\n};\n\nexport const formatDuration = (milliseconds: number): string => {\n if (milliseconds < 0) return '0s';\n\n const seconds = Math.floor(milliseconds / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) {\n return `${days}d ${hours % 24}h`;\n }\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m`;\n }\n\n if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n\n return `${seconds}s`;\n};\n\nexport const formatTimeAgo = (date: Date | string | number): string => {\n return formatRelativeTime(date);\n};\n\n// Number formatting utilities\nexport const formatNumber = (\n value: number,\n options: Intl.NumberFormatOptions = {},\n locale = 'en'\n): string => {\n try {\n return new Intl.NumberFormat(locale, options).format(value);\n } catch {\n return value.toString();\n }\n};\n\nexport const formatCurrency = (\n amount: number,\n currency = 'USD',\n locale = 'en'\n): string => {\n return formatNumber(amount, {\n style: 'currency',\n currency,\n }, locale);\n};\n\nexport const formatPercentage = (\n value: number,\n decimals = 1,\n locale = 'en'\n): string => {\n return formatNumber(value / 100, {\n style: 'percent',\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n }, locale);\n};\n\nexport const formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 B';\n\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${Number.parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n};\n\nexport const formatCompactNumber = (\n value: number,\n locale = 'en'\n): string => {\n if (Math.abs(value) < 1000) {\n return value.toString();\n }\n\n try {\n return new Intl.NumberFormat(locale, {\n notation: 'compact',\n compactDisplay: 'short',\n }).format(value);\n } catch {\n // Fallback for browsers that don't support compact notation\n const k = 1000;\n const sizes = ['', 'K', 'M', 'B', 'T'];\n const i = Math.floor(Math.log(Math.abs(value)) / Math.log(k));\n\n return `${Number.parseFloat((value / Math.pow(k, i)).toFixed(1))}${sizes[i]}`;\n }\n};\n\n// String formatting utilities\nexport const formatName = (firstName?: string, lastName?: string): string => {\n const parts = [firstName, lastName].filter(Boolean);\n return parts.join(' ');\n};\n\nexport const formatInitials = (name: string): string => {\n return name\n .split(' ')\n .map(word => word.charAt(0).toUpperCase())\n .slice(0, 2)\n .join('');\n};\n\nexport const formatDisplayName = (user: {\n firstName?: string;\n lastName?: string;\n username?: string;\n emailAddress?: string;\n}): string => {\n if (user.firstName || user.lastName) {\n return formatName(user.firstName, user.lastName);\n }\n\n if (user.username) {\n return user.username;\n }\n\n if (user.emailAddress) {\n return user.emailAddress.split('@')[0];\n }\n\n return 'Unknown User';\n};\n\nexport const formatEmail = (email: string): string => {\n return email.trim().toLowerCase();\n};\n\nexport const formatPhoneNumber = (\n phone: string,\n format: 'international' | 'national' | 'e164' = 'national'\n): string => {\n // Remove all non-digit characters except +\n const cleaned = phone.replace(/[^\\d+]/g, '');\n\n // Basic formatting for US numbers (extend as needed)\n if (cleaned.length === 10) {\n // US domestic number\n const match = cleaned.match(/^(\\d{3})(\\d{3})(\\d{4})$/);\n if (match) {\n switch (format) {\n case 'international':\n return `+1 ${match[1]} ${match[2]} ${match[3]}`;\n case 'e164':\n return `+1${cleaned}`;\n case 'national':\n default:\n return `(${match[1]}) ${match[2]}-${match[3]}`;\n }\n }\n }\n\n if (cleaned.length === 11 && cleaned.startsWith('1')) {\n // US number with country code\n const number = cleaned.substring(1);\n const match = number.match(/^(\\d{3})(\\d{3})(\\d{4})$/);\n if (match) {\n switch (format) {\n case 'international':\n return `+1 ${match[1]} ${match[2]} ${match[3]}`;\n case 'e164':\n return `+${cleaned}`;\n case 'national':\n default:\n return `(${match[1]}) ${match[2]}-${match[3]}`;\n }\n }\n }\n\n // For international numbers or unrecognized formats\n if (cleaned.startsWith('+')) {\n return cleaned;\n }\n\n return phone; // Return original if we can't format it\n};\n\nexport const maskEmail = (email: string): string => {\n const [localPart, domain] = email.split('@');\n if (!domain) return email;\n\n if (localPart.length <= 3) {\n return `${localPart[0]}***@${domain}`;\n }\n\n const firstChar = localPart[0];\n const lastChar = localPart[localPart.length - 1];\n const middleLength = Math.max(3, localPart.length - 2);\n\n return `${firstChar}${'*'.repeat(middleLength)}${lastChar}@${domain}`;\n};\n\nexport const maskPhoneNumber = (phone: string): string => {\n const cleaned = phone.replace(/[^\\d]/g, '');\n\n if (cleaned.length >= 10) {\n const lastFour = cleaned.slice(-4);\n const masked = '*'.repeat(cleaned.length - 4);\n return `${masked}${lastFour}`;\n }\n\n return phone;\n};\n\nexport const truncateText = (\n text: string,\n maxLength: number,\n suffix = '...'\n): string => {\n if (text.length <= maxLength) return text;\n\n const truncated = text.substring(0, maxLength - suffix.length);\n return truncated + suffix;\n};\n\nexport const truncateMiddle = (\n text: string,\n maxLength: number,\n separator = '...'\n): string => {\n if (text.length <= maxLength) return text;\n\n const sepLen = separator.length;\n const charsToShow = maxLength - sepLen;\n const frontChars = Math.ceil(charsToShow / 2);\n const backChars = Math.floor(charsToShow / 2);\n\n return text.substring(0, frontChars) +\n separator +\n text.substring(text.length - backChars);\n};\n\nexport const formatTextCase = (\n text: string,\n format: 'camel' | 'pascal' | 'snake' | 'kebab' | 'sentence' | 'title' | 'upper' | 'lower'\n): string => {\n switch (format) {\n case 'camel':\n return text.replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (word, index) => {\n return index === 0 ? word.toLowerCase() : word.toUpperCase();\n }).replace(/\\s+/g, '');\n\n case 'pascal':\n return text.replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (word) => {\n return word.toUpperCase();\n }).replace(/\\s+/g, '');\n\n case 'snake':\n return text.replace(/\\W+/g, ' ')\n .split(/ |\\B(?=[A-Z])/)\n .map(word => word.toLowerCase())\n .join('_');\n\n case 'kebab':\n return text.replace(/\\W+/g, ' ')\n .split(/ |\\B(?=[A-Z])/)\n .map(word => word.toLowerCase())\n .join('-');\n\n case 'sentence':\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();\n\n case 'title':\n return text.replace(/\\w\\S*/g, (txt) => {\n return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();\n });\n\n case 'upper':\n return text.toUpperCase();\n\n case 'lower':\n return text.toLowerCase();\n\n default:\n return text;\n }\n};\n\n// ID and token formatting utilities\nexport const formatId = (id: XID): string => {\n // Truncate long IDs for display\n if (id.length > 12) {\n return truncateMiddle(id, 12);\n }\n return id;\n};\n\nexport const formatTokenPreview = (token: string): string => {\n if (token.length <= 8) return token;\n\n const start = token.substring(0, 4);\n const end = token.substring(token.length - 4);\n return `${start}...${end}`;\n};\n\n// Address formatting utilities\nexport const formatAddress = (address: {\n street?: string;\n city?: string;\n state?: string;\n postalCode?: string;\n country?: string;\n}): string => {\n const parts = [\n address.street,\n address.city,\n address.state && address.postalCode\n ? `${address.state} ${address.postalCode}`\n : address.state || address.postalCode,\n address.country,\n ].filter(Boolean);\n\n return parts.join(', ');\n};\n\n// List formatting utilities\nexport const formatList = (\n items: string[],\n options: {\n style?: 'long' | 'short' | 'narrow';\n type?: 'conjunction' | 'disjunction';\n locale?: string;\n } = {}\n): string => {\n const { style = 'long', type = 'conjunction', locale = 'en' } = options;\n\n if (items.length === 0) return '';\n if (items.length === 1) return items[0];\n\n try {\n return new Intl.DateTimeFormat(locale, { style, type }).format(items);\n } catch {\n // Fallback for browsers that don't support Intl.ListFormat\n if (items.length === 2) {\n return `${items[0]} ${type === 'conjunction' ? 'and' : 'or'} ${items[1]}`;\n }\n\n const lastItem = items[items.length - 1];\n const otherItems = items.slice(0, -1);\n const connector = type === 'conjunction' ? 'and' : 'or';\n\n return `${otherItems.join(', ')}, ${connector} ${lastItem}`;\n }\n};\n\n// JSON formatting utilities\nexport const formatJSON = (\n obj: any,\n indent = 2,\n maxDepth = 10\n): string => {\n try {\n return JSON.stringify(obj, null, indent);\n } catch {\n return '[Circular Reference]';\n }\n};\n\nexport const formatJSONCompact = (obj: any): string => {\n try {\n return JSON.stringify(obj);\n } catch {\n return '[Circular Reference]';\n }\n};\n\n// URL formatting utilities\nexport const formatDomain = (url: string): string => {\n try {\n const urlObj = new URL(url);\n return urlObj.hostname;\n } catch {\n return url;\n }\n};\n\nexport const formatURL = (url: string): string => {\n if (!url.startsWith('http://') && !url.startsWith('https://')) {\n return `https://${url}`;\n }\n return url;\n};\n\n// Color formatting utilities\nexport const formatHexColor = (color: string): string => {\n const hex = color.replace('#', '');\n\n // Expand short hex to full hex\n if (hex.length === 3) {\n return `#${hex.split('').map(char => char + char).join('')}`;\n }\n\n if (hex.length === 6) {\n return `#${hex}`;\n }\n\n return color;\n};\n\nexport const formatRGBColor = (r: number, g: number, b: number): string => {\n return `rgb(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)})`;\n};\n\nexport const formatRGBAColor = (r: number, g: number, b: number, a: number): string => {\n return `rgba(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}, ${a})`;\n};\n\n// Validation message formatting\nexport const formatValidationError = (\n field: string,\n rule: string,\n value?: any\n): string => {\n const fieldName = formatTextCase(field, 'sentence');\n\n switch (rule) {\n case 'required':\n return `${fieldName} is required`;\n case 'email':\n return `${fieldName} must be a valid email address`;\n case 'minLength':\n return `${fieldName} must be at least ${value} characters`;\n case 'maxLength':\n return `${fieldName} must be no more than ${value} characters`;\n case 'pattern':\n return `${fieldName} format is invalid`;\n case 'number':\n return `${fieldName} must be a number`;\n case 'min':\n return `${fieldName} must be at least ${value}`;\n case 'max':\n return `${fieldName} must be no more than ${value}`;\n default:\n return `${fieldName} is invalid`;\n }\n};\n\nexport function getTitleAlignment(align: 'left' | 'center' | 'right'): string {\n switch (align) {\n case 'left':\n return 'text-left';\n case 'center':\n return 'text-center';\n case 'right':\n return 'text-right';\n default:\n return 'text-left';\n }\n}\n\n// Export utilities object\nexport const FormatUtils = {\n // Date and time\n formatDate,\n formatDateTime,\n formatTime,\n formatRelativeTime,\n formatDuration,\n formatTimeAgo,\n\n // Numbers\n formatNumber,\n formatCurrency,\n formatPercentage,\n formatFileSize,\n formatCompactNumber,\n\n // Strings\n formatName,\n formatInitials,\n formatDisplayName,\n formatEmail,\n formatPhoneNumber,\n maskEmail,\n maskPhoneNumber,\n truncateText,\n truncateMiddle,\n formatTextCase,\n\n // IDs and tokens\n formatId,\n formatTokenPreview,\n\n // Addresses\n formatAddress,\n\n // Lists\n formatList,\n\n // JSON\n formatJSON,\n formatJSONCompact,\n\n // URLs\n formatDomain,\n formatURL,\n\n // Colors\n formatHexColor,\n formatRGBColor,\n formatRGBAColor,\n\n // Validation\n formatValidationError,\n};"],"names":["formatDate","date","options","locale","dateObj","defaultOptions","formatDateTime","formatTime","formatRelativeTime","diffInSeconds","diffInMinutes","diffInHours","diffInDays","diffInWeeks","diffInMonths","diffInYears","formatDuration","milliseconds","seconds","minutes","hours","days","formatTimeAgo","formatNumber","value","formatCurrency","amount","currency","formatPercentage","decimals","formatFileSize","bytes","k","sizes","i","formatCompactNumber","formatName","firstName","lastName","formatInitials","name","word","formatDisplayName","user","formatEmail","email","formatPhoneNumber","phone","format","cleaned","match","maskEmail","localPart","domain","firstChar","lastChar","middleLength","maskPhoneNumber","lastFour","truncateText","text","maxLength","suffix","truncateMiddle","separator","sepLen","charsToShow","frontChars","backChars","formatTextCase","index","txt","formatId","id","formatTokenPreview","token","start","end","formatAddress","address","formatList","items","style","type","lastItem","otherItems","connector","formatJSON","obj","indent","maxDepth","formatJSONCompact","formatDomain","url","formatURL","formatHexColor","color","hex","char","formatRGBColor","r","g","b","formatRGBAColor","a","formatValidationError","field","rule","fieldName","getTitleAlignment","align","FormatUtils"],"mappings":"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"}