2020-07-31 20:48:15 +00:00
|
|
|
// License: LGPL-3.0-or-later
|
|
|
|
|
|
|
|
import * as React from "react";
|
2020-10-24 19:46:36 +00:00
|
|
|
import { useIntl as useIntlParent,
|
|
|
|
IntlShape as IntlShapeParent,
|
|
|
|
IntlProvider as IntlProviderParent,
|
|
|
|
createIntl as createIntlParent} from "react-intl";
|
2020-07-31 20:48:15 +00:00
|
|
|
import { Money } from "../../common/money";
|
2020-10-24 19:46:36 +00:00
|
|
|
import { IntlContext } from "../../hooks/useIntl";
|
|
|
|
import type {IntlShape, FormatMoneyOptions} from '../../hooks/useIntl';
|
2020-07-31 20:48:15 +00:00
|
|
|
|
2020-10-24 19:46:36 +00:00
|
|
|
|
|
|
|
function rawFormatMoney(intl:IntlShapeParent, amount:Money, opts?:FormatMoneyOptions) : string {
|
2020-07-31 20:48:15 +00:00
|
|
|
const formatter = intl.formatters.getNumberFormat(intl.locale, {...opts,
|
|
|
|
style: 'currency',
|
|
|
|
currency: amount.currency.toUpperCase(),
|
|
|
|
});
|
|
|
|
|
2020-09-14 17:25:15 +00:00
|
|
|
const adjustedAmount = amount.toBigNumber().dividedBy(Math.pow(10, formatter.resolvedOptions().maximumFractionDigits));
|
|
|
|
return formatter.format(adjustedAmount.toNumber());
|
2020-07-31 20:48:15 +00:00
|
|
|
}
|
|
|
|
|
2020-10-20 21:57:09 +00:00
|
|
|
/**
|
|
|
|
* Use this to scope a context to a tree of components.
|
|
|
|
* Works like [IntlProvider}(https://formatjs.io/docs/react-intl/components#intlprovider)
|
|
|
|
* But includes support for formatting money based on the current locale.
|
|
|
|
*
|
|
|
|
* @export
|
2020-10-24 19:46:36 +00:00
|
|
|
* @param {ConstructorParameters<typeof IntlProviderParent>[0]} props
|
2020-10-20 21:57:09 +00:00
|
|
|
* @returns {JSX.Element}
|
|
|
|
*/
|
2020-10-24 19:46:36 +00:00
|
|
|
export default function IntlProvider(props:ConstructorParameters<typeof IntlProviderParent>[0]) : JSX.Element {
|
|
|
|
return <IntlProviderParent {...props}>
|
2020-07-31 20:48:15 +00:00
|
|
|
<InnerProvider>
|
|
|
|
{props.children}
|
|
|
|
</InnerProvider>
|
2020-10-24 19:46:36 +00:00
|
|
|
</IntlProviderParent>;
|
2020-07-31 20:48:15 +00:00
|
|
|
}
|
|
|
|
|
2020-10-20 21:57:09 +00:00
|
|
|
function InnerProvider({children}:{children:React.ReactNode}) : JSX.Element {
|
2020-10-24 19:46:36 +00:00
|
|
|
const intl = useIntlParent();
|
2020-07-31 20:48:15 +00:00
|
|
|
const formatMoney = React.useCallback((amount:Money, opts?:FormatMoneyOptions) => {
|
|
|
|
return rawFormatMoney(intl, amount, opts);
|
|
|
|
}, [intl]);
|
|
|
|
|
|
|
|
const houdiniIntl = { ...intl, formatMoney};
|
2020-10-24 19:46:36 +00:00
|
|
|
return <IntlContext.Provider value={houdiniIntl}>
|
2020-07-31 20:48:15 +00:00
|
|
|
{children}
|
2020-10-24 19:46:36 +00:00
|
|
|
</IntlContext.Provider>;
|
2020-07-31 20:48:15 +00:00
|
|
|
}
|
|
|
|
|
2020-10-24 19:46:36 +00:00
|
|
|
export function createIntl(...props:Parameters<typeof createIntlParent>) : IntlShape {
|
|
|
|
const intl = createIntlParent(...props);
|
2020-07-31 20:48:15 +00:00
|
|
|
const formatMoney = (amount:Money, opts?:FormatMoneyOptions) => rawFormatMoney(intl, amount, opts);
|
|
|
|
|
|
|
|
return {...intl, formatMoney};
|
|
|
|
}
|