60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import RatingBadge from "~/components/ui/badges/RatingBadge";
|
|
import { createLocaleFormatters, type LocaleFormatters, useLocaleFormatters } from "~/locale/format";
|
|
|
|
export type NumberFormatType = "integer" | "decimal" | "currency" | "percentage" | "rating";
|
|
|
|
const fallbackFormatters = createLocaleFormatters("en");
|
|
const defaultCurrency = "USD";
|
|
type NumberOptions = Parameters<LocaleFormatters["number"]>[1];
|
|
const fixedDecimalOptions: NumberOptions = { minimumFractionDigits: 2, maximumFractionDigits: 2 };
|
|
|
|
export function getNumberAsStringValue({
|
|
value,
|
|
format,
|
|
currencySymbol,
|
|
formatters = fallbackFormatters,
|
|
}: {
|
|
value?: number | null;
|
|
format?: NumberFormatType;
|
|
currencySymbol?: string;
|
|
formatters?: LocaleFormatters;
|
|
}) {
|
|
if (value === null || value === undefined) {
|
|
return "";
|
|
}
|
|
switch (format) {
|
|
case "integer":
|
|
return formatters.number(value, { maximumFractionDigits: 0 });
|
|
case "decimal":
|
|
return formatters.number(value, fixedDecimalOptions);
|
|
case "currency":
|
|
return currencySymbol ? `${currencySymbol}${formatters.number(value, fixedDecimalOptions)}` : formatters.currency(value, defaultCurrency, fixedDecimalOptions);
|
|
case "percentage":
|
|
return formatters.percent(value / 100, fixedDecimalOptions);
|
|
default:
|
|
return formatters.number(value);
|
|
}
|
|
}
|
|
export default function RowNumberCell({ value, format, currencySymbol }: { value?: number | null; format?: NumberFormatType; currencySymbol?: string }) {
|
|
const formatters = useLocaleFormatters();
|
|
const formattedValue = getNumberAsStringValue({ value, format, currencySymbol, formatters });
|
|
|
|
return (
|
|
<>
|
|
{value === null || value === undefined ? (
|
|
<div></div>
|
|
) : (
|
|
<div>
|
|
{format === "rating" ? (
|
|
<span>
|
|
<RatingBadge value={value} />
|
|
</span>
|
|
) : (
|
|
<span>{formattedValue}</span>
|
|
)}
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|