import { cn } from '@/lib/utils'; export interface NumericProps extends React.HTMLAttributes { /** The numeric value to display. */ value: number; /** Format style. Default 'vnd'. */ format?: 'vnd' | 'percent' | 'decimal' | 'compact'; /** Number of fraction digits for percent/decimal. Default 1 for percent, 0 for vnd. */ fractionDigits?: number; } const vndFormatter = new Intl.NumberFormat('vi-VN', { style: 'currency', currency: 'VND', maximumFractionDigits: 0, }); const compactFormatter = new Intl.NumberFormat('vi-VN', { notation: 'compact', maximumFractionDigits: 1, }); function formatValue( value: number, format: NumericProps['format'], fractionDigits?: number, ): string { switch (format) { case 'percent': return `${value >= 0 ? '+' : ''}${value.toFixed(fractionDigits ?? 1)}%`; case 'decimal': return new Intl.NumberFormat('vi-VN', { minimumFractionDigits: fractionDigits ?? 0, maximumFractionDigits: fractionDigits ?? 2, }).format(value); case 'compact': return compactFormatter.format(value); case 'vnd': default: return vndFormatter.format(value); } } /** * Numeric display — right-aligned, tabular-nums, formatted for VND/percent. * Automatically sets `data-numeric` for global tabular-nums styling. */ export function Numeric({ value, format = 'vnd', fractionDigits, className, ...props }: NumericProps) { return ( {formatValue(value, format, fractionDigits)} ); }