pagamio-frontend-commons-lib
Version:
Pagamio library for Frontend reusable components like the form engine and table container
78 lines (77 loc) • 3.07 kB
JavaScript
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs) {
return twMerge(clsx(inputs));
}
/**
* Formats a number as currency using en-US locale standards.
*
* @param {number} price - The numeric value to format as currency
* @param {string} [currency="ZAR"] - ISO 4217 currency code (default: "ZAR")
* @param {number} [minimumFractionDigits=2] - Minimum fraction digits (default: 2)
* @param {number} [maximumFractionDigits] - Optional maximum fraction digits
* @param {string} [displaySymbol] - Optional custom symbol to display instead of ISO code
* @returns {string} Formatted currency string
*
* @example
* // Basic usage with ZAR (South African Rand)
* formatPrice(1234.56); // Returns "ZAR 1,234.56"
*
* @example
* // USD with 2 decimal places
* formatPrice(1234.56, "USD"); // Returns "$1,234.56"
*
* @example
* // Euro with standard formatting
* formatPrice(1234.56, "EUR"); // Returns "€1,234.56"
*
* @example
* // Custom display symbol for ZAR
* formatPrice(1234.56, "ZAR", 2, undefined, "R"); // Returns "R 1,234.56"
*
* @example
* // Custom decimal places (clamping)
* formatPrice(1234.5678, "GBP", 2, 3); // Returns "£1,234.568"
*
* @example
* // Fallback behavior with invalid currency
* formatPrice(1234.56, "XYZ"); // Returns "XYZ 1,234.56"
*/
export const formatPrice = (price, currency = 'ZAR', minimumFractionDigits = 2, maximumFractionDigits, displaySymbol) => {
const options = {
style: 'currency',
currency,
minimumFractionDigits,
};
if (maximumFractionDigits !== undefined) {
options.maximumFractionDigits = maximumFractionDigits;
}
try {
const formatted = price.toLocaleString('en-US', options);
// If a custom display symbol is provided, replace the currency symbol/code
if (displaySymbol) {
// Handle different currency formats by finding and replacing the currency part
// For currencies like USD ($1,234.56), EUR (€1,234.56), GBP (£1,234.56)
const symbolRegex = /^[^\d\s,.-]+/;
const symbolMatch = symbolRegex.exec(formatted);
if (symbolMatch) {
return formatted.replace(symbolMatch[0], displaySymbol);
}
// For currencies that show as codes like ZAR (ZAR 1,234.56)
const codeRegex = /^[A-Z]{3}\s/;
const codeMatch = codeRegex.exec(formatted);
if (codeMatch) {
return formatted.replace(codeMatch[0], `${displaySymbol} `);
}
// Fallback: just replace the currency code anywhere in the string
return formatted.replace(currency, displaySymbol);
}
return formatted;
}
catch (error) {
console.error('Error formatting currency:', error);
// Fallback to basic formatting when Intl fails
const fallbackFormatted = `${displaySymbol || currency} ${price.toLocaleString('en-US', { minimumFractionDigits })}`;
return fallbackFormatted;
}
};