57 lines
2 KiB
TypeScript
57 lines
2 KiB
TypeScript
|
// License: LGPL-3.0-or-later
|
||
|
|
||
|
import * as React from "react";
|
||
|
import { useIntl, FormatNumberOptions, IntlShape, IntlProvider, createIntl} from "react-intl";
|
||
|
import { Money } from "../../common/money";
|
||
|
|
||
|
export declare type FormatMoneyOptions = Omit<FormatNumberOptions,'style'|'unit'|'unitDisplay'|'currency'>;
|
||
|
|
||
|
export declare type HoudiniIntlShape = IntlShape & {formatMoney:(amount:Money, opts?:FormatMoneyOptions) => string}
|
||
|
|
||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||
|
const HoudiniIntlContext = React.createContext<HoudiniIntlShape>(null as any);
|
||
|
|
||
|
function rawFormatMoney(intl:IntlShape, amount:Money, opts?:FormatMoneyOptions) : string {
|
||
|
const formatter = intl.formatters.getNumberFormat(intl.locale, {...opts,
|
||
|
style: 'currency',
|
||
|
currency: amount.currency.toUpperCase(),
|
||
|
});
|
||
|
|
||
|
const adjustedAmount = amount.amount / Math.pow(10, formatter.resolvedOptions().maximumFractionDigits);
|
||
|
return formatter.format(adjustedAmount);
|
||
|
}
|
||
|
|
||
|
export function useHoudiniIntl() : HoudiniIntlShape {
|
||
|
const context = React.useContext(HoudiniIntlContext);
|
||
|
return context;
|
||
|
}
|
||
|
|
||
|
export function HoudiniIntlProvider(props:ConstructorParameters<typeof IntlProvider>[0]) : JSX.Element {
|
||
|
return <IntlProvider {...props}>
|
||
|
<InnerProvider>
|
||
|
{props.children}
|
||
|
</InnerProvider>
|
||
|
</IntlProvider>;
|
||
|
}
|
||
|
|
||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||
|
function InnerProvider({children}:React.PropsWithChildren<{}>) : JSX.Element {
|
||
|
const intl = useIntl();
|
||
|
const formatMoney = React.useCallback((amount:Money, opts?:FormatMoneyOptions) => {
|
||
|
return rawFormatMoney(intl, amount, opts);
|
||
|
}, [intl]);
|
||
|
|
||
|
const houdiniIntl = { ...intl, formatMoney};
|
||
|
return <HoudiniIntlContext.Provider value={houdiniIntl}>
|
||
|
{children}
|
||
|
</HoudiniIntlContext.Provider>;
|
||
|
}
|
||
|
|
||
|
|
||
|
export function createHoudiniIntl(...props:Parameters<typeof createIntl>) : HoudiniIntlShape {
|
||
|
|
||
|
const intl = createIntl(...props);
|
||
|
const formatMoney = (amount:Money, opts?:FormatMoneyOptions) => rawFormatMoney(intl, amount, opts);
|
||
|
|
||
|
return {...intl, formatMoney};
|
||
|
}
|