import type { HTMLAttributes } from "react";
import { useFieldValue, useTranslate } from "ra-core";
import type { FieldProps } from "@/lib/field.type";
/**
* Displays a numeric value with locale-specific formatting.
*
* This field automatically formats numbers according to the user's locale using Intl.NumberFormat.
* It supports custom locales and formatting options for currencies, percentages, and more.
* To be used with RecordField or DataTable.Col components, or anywhere a RecordContext is available.
*
* @see {@link https://marmelab.com/shadcn-admin-kit/docs/numberfield/ NumberField documentation}
*
* @example
* import { Show, RecordField, NumberField } from '@/components/admin';
*
* const ProductShow = () => (
*
*
*
*
*
*
*
*
* );
*/
export const NumberField = <
RecordType extends Record = Record,
>({
defaultValue,
source,
record,
empty,
transform = defaultTransform,
locales,
options,
...rest
}: NumberFieldProps) => {
let value = useFieldValue({ defaultValue, source, record });
const translate = useTranslate();
if (value == null) {
if (!empty) {
return null;
}
return (
{typeof empty === "string" ? translate(empty, { _: empty }) : empty}
);
}
if (transform) {
value = transform(value);
}
return (
{hasNumberFormat && typeof value === "number"
? value.toLocaleString(locales, options)
: value}
);
};
export interface NumberFieldProps<
RecordType extends Record = Record,
> extends FieldProps,
HTMLAttributes {
locales?: string | string[];
options?: object;
transform?: (value: any) => number;
}
const defaultTransform = (value: any) =>
value && typeof value === "string" && !isNaN(value as any) ? +value : value;
const hasNumberFormat = !!(
typeof Intl === "object" &&
Intl &&
typeof Intl.NumberFormat === "function"
);