2020-08-10 18:29:17 +00:00
|
|
|
|
|
|
|
// License: LGPL-3.0-or-later
|
|
|
|
import * as React from "react";
|
|
|
|
|
|
|
|
import MuiTextField from '@material-ui/core/TextField';
|
|
|
|
import { fieldToTextField, TextFieldProps } from 'formik-material-ui';
|
|
|
|
import { Money } from "../../common/money";
|
2020-10-24 19:46:36 +00:00
|
|
|
import { useIntl } from "../intl";
|
2020-08-10 18:29:17 +00:00
|
|
|
import { useEffect, useRef } from "react";
|
|
|
|
|
|
|
|
import {useI18nCurrencyInput, Types} from '@houdiniproject/react-i18n-currency-input';
|
2020-10-08 20:39:51 +00:00
|
|
|
import '../../common/intl-polyfills/numberFormat';
|
2020-08-10 18:29:17 +00:00
|
|
|
|
|
|
|
export interface UseSerializeMoneyProps extends Omit<Types.UseI18nCurrencyInputProps, 'currency' | 'locale'|'value'> {
|
2020-10-22 19:27:07 +00:00
|
|
|
value:Money;
|
2020-08-10 18:29:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hook for serializing a Money object to a string and back again. Particularly
|
|
|
|
* useful for text fields.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
* let money = new Money(100, 'usd')
|
|
|
|
* let { serializedAmount, handleChange} = useSerializeMoney(money, (amount) => {money = amount})
|
|
|
|
*
|
|
|
|
* // serializedAmount gets $1.00 as a string. handleChange receives the new serializedvalue after a change
|
|
|
|
* @param inputAmount a Money object
|
|
|
|
* @param setOutputAmount used for passing up output of the Hook
|
|
|
|
*/
|
|
|
|
export function useSerializeMoney(props:UseSerializeMoneyProps) : ReturnType<typeof useI18nCurrencyInput> {
|
2020-10-24 19:46:36 +00:00
|
|
|
const intl = useIntl();
|
2020-08-10 18:29:17 +00:00
|
|
|
const {locale} = intl;
|
|
|
|
const {value, ...other} = props;
|
|
|
|
const {amount, currency} = value;
|
|
|
|
|
|
|
|
const i18n = useI18nCurrencyInput({...other, locale,
|
|
|
|
currency,
|
2020-09-30 17:05:22 +00:00
|
|
|
value:amount,
|
2020-08-10 18:29:17 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return {...i18n};
|
|
|
|
}
|
|
|
|
|
|
|
|
export type IMoneyTextFieldProps = Omit<TextFieldProps,'value'> &
|
|
|
|
Omit<Types.UseI18nCurrencyInputProps, 'currency' | 'locale'|'value'| 'inputRef'|'inputType'> &
|
|
|
|
{ value:Money };
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A text field which accepts a Money value, uses useI18nCurrencyInput and returns a Money value for various callbacks
|
|
|
|
*
|
|
|
|
* @param {IMoneyTextFieldProps} { children, form, field, currencyDisplay, useGrouping, allowEmpty, selectAllOnFocus, ...props }
|
|
|
|
* @returns {JSX.Element}
|
|
|
|
*/
|
|
|
|
function MoneyTextField({ children, form, field, currencyDisplay, useGrouping, allowEmpty, selectAllOnFocus, ...props }:IMoneyTextFieldProps) : JSX.Element {
|
|
|
|
const {name:fieldName, value} = field;
|
|
|
|
|
|
|
|
const inputRef = useRef<HTMLInputElement>();
|
|
|
|
|
|
|
|
const {currency} = value;
|
|
|
|
|
|
|
|
const { maskedValue, valueInCents,
|
|
|
|
onChange,
|
|
|
|
onFocus,
|
|
|
|
onMouseUp,
|
|
|
|
onSelect } = useSerializeMoney({ inputRef, value, currencyDisplay, useGrouping, allowEmpty, selectAllOnFocus});
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
form.setFieldValue(fieldName, Money.fromCents(valueInCents, currency));
|
|
|
|
|
2020-11-06 21:58:50 +00:00
|
|
|
}, [fieldName, valueInCents, currency, form]);
|
2020-08-10 18:29:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
return <MuiTextField {...fieldToTextField({form, field, ...props})} value={maskedValue}
|
|
|
|
onChange={onChange} onFocus={onFocus} onMouseUp={onMouseUp} onSelect={onSelect} inputRef={inputRef}>
|
|
|
|
{children}
|
|
|
|
</MuiTextField>;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export default MoneyTextField;
|