<!-- THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -->
<!-- This file is created by the `pnpm generate-readme` script. -->

# LocalizedMoneyInput

## Description

A controlled input component for localized money values with validation states.

## Installation

```
pnpm add @commercetools-uikit/localized-money-input
```

```
npm --save install @commercetools-uikit/localized-money-input
```

Additionally install the peer dependencies (if not present)

```
pnpm add react react-dom react-intl
```

```
npm --save install react react-dom react-intl
```

## Usage

```jsx
import LocalizedMoneyInput from '@commercetools-uikit/localized-money-input';

const Example = () => (
  <LocalizedMoneyInput
    value={{
      USD: { currencyCode: 'USD', amount: '12.22' },
      EUR: { currencyCode: 'EUR', amount: '41.44' },
    }}
    onChange={
      (/** event */) => {
        // alert(event.target.name, event.target.value)
      }
    }
  />
);

export default Example;
```

## Properties

| Props                           | Type                                                                                                  | Required | Default   | Description                                                                                                                                                                                                                                                                      |
| ------------------------------- | ----------------------------------------------------------------------------------------------------- | :------: | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                            | `string`                                                                                              |          |           | Used as HTML id property.                                                                                                                                                                                                                                                        |
| `name`                          | `string`                                                                                              |          |           | The prefix used to create a HTML `name` property for the amount input field (`${name}.amount`).                                                                                                                                                                                  |
| `value`                         | `Record`                                                                                              |    ✅    |           | value of possible currency&#xA;<br/>&#xA;the input doesn't accept a "currencies" prop, instead all possible&#xA;currencies have to exist (with empty or filled strings) on the value:&#xA;{ EUR: {amount: '12.00', currencyCode: 'EUR'}, USD: {amount: '', currencyCode: 'USD'}} |
| `onChange`                      | `Function`<br/>[See signature.](#signature-onchange)                                                  |          |           | Called with the event of the input.                                                                                                                                                                                                                                              |
| `selectedCurrency`              | `string`                                                                                              |    ✅    |           | the currently selected currency                                                                                                                                                                                                                                                  |
| `onBlur`                        | `Function`<br/>[See signature.](#signature-onblur)                                                    |          |           | Called when input is blurred                                                                                                                                                                                                                                                     |
| `onFocus`                       | `Function`<br/>[See signature.](#signature-onfocus)                                                   |          |           | Called when input is focused                                                                                                                                                                                                                                                     |
| `hideCurrencyExpansionControls` | `boolean`                                                                                             |          |           | Will hide the currency expansion controls when set to `true`. All currencies will be shown when set to `true`.                                                                                                                                                                   |
| `defaultExpandCurrencies`       | `boolean`                                                                                             |          |           | Controls whether one or all currencirs are visible by default                                                                                                                                                                                                                    |
| `isCondensed`                   | `boolean`                                                                                             |          |           | Use this property to reduce the paddings of the component for a ui compact variant                                                                                                                                                                                               |
| `isDisabled`                    | `boolean`                                                                                             |          |           | Indicates that the input cannot be modified (e.g not authorized, or changes currently saving).                                                                                                                                                                                   |
| `isReadOnly`                    | `boolean`                                                                                             |          |           | Indicates that the field is displaying read-only content                                                                                                                                                                                                                         |
| `placeholder`                   | `Record`                                                                                              |          |           | Placeholder text for the input                                                                                                                                                                                                                                                   |
| `horizontalConstraint`          | `union`<br/>Possible values:<br/>`, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 'scale', 'auto'` |          | `'scale'` | Horizontal size limit of the input fields.                                                                                                                                                                                                                                       |
| `hasError`                      | `boolean`                                                                                             |          |           | Indicates that input has errors                                                                                                                                                                                                                                                  |
| `hasWarning`                    | `boolean`                                                                                             |          |           | Control to indicate on the input if there are values that are potentially invalid                                                                                                                                                                                                |
| `errors`                        | `Record`                                                                                              |          |           | A map of errors. Error messages for known errors are rendered automatically.&#xA;<br>&#xA;Unknown errors will be forwarded to `renderError`                                                                                                                                      |
| `warnings`                      | `Record`                                                                                              |          |           | A map of warnings.                                                                                                                                                                                                                                                               |
| `hasHighPrecisionBadge`         | `boolean`                                                                                             |          |           | Shows high precision badge in case current value uses high precision.                                                                                                                                                                                                            |

## Signatures

### Signature `onChange`

```ts
(event: TCustomEvent) => void
```

### Signature `onBlur`

```ts
(event: TCustomEvent) => void
```

### Signature `onFocus`

```ts
(event: TCustomEvent) => void
```

## Static methods

### `LocalizedMoneyInput.getEmptyCurrencies`

Returns array of the empty currencies

```js
LocalizedMoneyInput.getEmptyCurrencies({});
// -> []
```

```js
LocalizedMoneyInput.getEmptyCurrencies({
  USD: { currencyCode: 'USD', amount: '' },
  EUR: { currencyCode: 'EUR', amount: '' },
});
// -> ['USD', 'EUR']
```

```js
LocalizedMoneyInput.getEmptyCurrencies({
  USD: { currencyCode: 'USD', amount: '12.43' },
  EUR: { currencyCode: 'EUR', amount: '' },
});
// -> ['EUR']
```

### `LocalizedMoneyInput.getHighPrecisionCurrencies`

Returns array of the currencies that have high precision amount

```js
LocalizedMoneyInput.getHighPrecisionCurrencies({});
// -> []
```

```js
LocalizedMoneyInput.getHighPrecisionCurrencies({
  USD: {
    currencyCode: 'USD',
    amount: '12.2221',
  },
  EUR: {
    currencyCode: 'EUR',
    amount: '9.9999',
  },
});
// -> ['USD', 'EUR']
```

```js
LocalizedMoneyInput.getHighPrecisionCurrencies({
  USD: {
    currencyCode: 'USD',
    amount: '12.43',
  },
  EUR: {
    currencyCode: 'EUR',
    amount: '0.00001',
  },
});
// -> ['EUR']
```

### `LocalizedMoneyInput.convertToMoneyValues`

The convertToMoneyValues function will turn a list of `LocalizedMoneyInput` values into a list of [`MoneyValue`](https://docs.commercetools.com/http-api-types#money) the API can handle. It automatically converts to `centPrecision` or `highPrecision` types when the number of supplied fraction digits exceeds the number of fraction digits used by the currency. If you want to forbid `highPrecision`, then the form's validation needs to add an error when it sees a `highPrecision` price. See example below.

Here are examples of `centPrecision` and `highPrecision` prices.

```js
// 42.00 €
[
  {
    type: 'centPrecision',
    currencyCode: 'EUR',
    centAmount: 4200,
    fractionDigits: 2,
  },
];
```

```js
// 0.0123456 €
[
  {
    type: 'highPrecision',
    currencyCode: 'EUR',
    centAmount: 1,
    preciseAmount: 123456,
    fractionDigits: 7,
  },
];
```

### `LocalizedMoneyInput.parseMoneyValues`

The `parseMoneyValues` function will turn a list of `MoneyValue` into a record of values the `LocalizedMoneyInput` component can handle.

```js
LocalizedMoneyInput.parseMoneyValues([{ currencyCode: 'EUR', centAmount: 10 }]);

// -> { EUR: { currencyCode: 'EUR', centAmount: 10 } }
```

### `LocalizedMoneyInput.getEmptyCurrencies`

The getEmptyCurrencies function will return array of currencies that don't have amount .

```js
LocalizedMoneyInput.getEmptyCurrencies({
  EUR: { currencyCode: 'EUR', amount: '' },
  USD: { currencyCode: 'USD', amount: '12.77' },
}); // -> ['EUR']
LocalizedMoneyInput.getEmptyCurrencies({
  EUR: { currencyCode: 'EUR', amount: '12.77' },
}); // -> []
```

## Examples

Here's an example of how `LocalizedMoneyInput` would be used inside a form.

```jsx
import { IntlProvider } from 'react-intl';
import { Formik } from 'formik';
import omitEmpty from 'omit-empty-es';
import { ErrorMessage } from '@commercetools-uikit/messages';
import LocalizedMoneyInput from '@commercetools-uikit/localized-money-input';
// the existing document, e.g. from the database
const doc = {
  prices: [
    {
      currencyCode: 'EUR',
      centAmount: 1200,
    },
    {
      currencyCode: 'AMD',
      centAmount: 3300,
    },
  ],
};
// A function to convert a document to form values.
const docToFormValues = (doc) => ({
  // The parseMoneyValue function will turn a MoneyValue into a
  // value the LocalizedMoneyInput component can handle ({currency: amount})
  prices: LocalizedMoneyInput.parseMoneyValues(doc.prices),
});
// a function to convert form values back to a document
const formValuesToDoc = (formValues) => ({
  // The convertToMoneyValue function will convert a LocalizedMoneyInput
  // value into a value the API can handle
  // It automatically converts to centPrecision or highPrecision
  // depending on the number of supplied fraction digits and the
  // used currency code.
  // If you want to forbid highPrecision, then the form's validation
  // needs to add an error when it sees a highPrecision price.
  // See example below
  prices: LocalizedMoneyInput.convertToMoneyValues(formValues.prices),
});
const validate = (formValues) => {
  const errors = { prices: {} };
  Object.keys(formValues.prices).forEach((currency) => {
    errors.prices[currency] = {};
  });
  const emptyCurrencies = LocalizedMoneyInput.getEmptyCurrencies(
    formValues.prices
  );
  // ['EUR', 'USD']
  // This form doesn't accept high precision prices
  const highPrecisionCurrencies =
    LocalizedMoneyInput.getHighPrecisionCurrencies(formValues.prices);
  // ['CAD', 'USD']
  emptyCurrencies.forEach((emptyCurrency) => {
    errors.prices[emptyCurrency].missing = true;
  });
  highPrecisionCurrencies.forEach((highPrecisionCurrency) => {
    errors.prices[highPrecisionCurrency].highPrecision = true;
  });
  return omitEmpty(errors);
};
const initialValues = docToFormValues(doc);
const renderErrors = (errors) => {
  Object.keys(errors.prices).reduce((currency) => {
    const error =
      (errors.prices[currency] && errors.prices[currency].missing && (
        <ErrorMessage>This field is required!</ErrorMessage>
      )) ||
      (errors.prices[currency] && errors.prices[currency].highPrecision && (
        <ErrorMessage>High precision prices not supported here!</ErrorMessage>
      ));
    return {
      [currency]: touched.prices[currency] && error,
    };
  });
};
return (
  <Formik
    initialValues={initialValues}
    validate={validate}
    onSubmit={(formValues) => {
      // doc will contain "prices" holding a MoneyValue,
      // ready to be consumed by the API
      const nextDoc = formValuesToDoc(formValues);
      console.log(nextDoc);
    }}
    render={({
      values,
      errors,
      handleChange,
      handleBlur,
      handleSubmit,
      isSubmitting,
    }) => (
      <form onSubmit={handleSubmit}>
        <LocalizedMoneyInput
          value={values.prices}
          onChange={handleChange}
          onBlur={handleBlur}
          isDisabled={isSubmitting}
          errors={renderErrors(errors)}
          horizontalConstraint={10}
        />
        <button type="submit">Submit</button>
      </form>
    )}
  />
);
```
