react-i18n-currency-input (inspired by react-currency-input)
An Typescript react component for currency using the ECMAScript Internationalization API based upon react-currency-input.
The package also includes a corresponding hook (useI18nCurrencyInput) if you'd like to add the functionality to your own component.
useI18nCurrencyInputnow will recognize when the value passed in via args is updated.react-useis no longer a peer dependency (usePreviousis embedded in the build becuase it's small)- Strict mode on for Typescript
requireSignis no longer passed through to the Input element, as-is it shouldn't be
- Move to React hook-based components
- Add React hook for advanced usage (useI18nCurrencyInput)
- Update dependencies
- Simplify build to use webpack
- Add storybook for development use
Initial release
yarn install @houdiniproject/react-i18n-currency-input
You can store the value passed in to the change handler in your state.
import * as React from 'react'
import I18nCurrencyInput from 'react-i18n-currency-input';
function MyApp(props: {value:number|string|null}) {
const [value,setValue] = useState(props.value)
const onChange = useCallback((maskedValue, value, valueInCents) => {
// you'll want to pass maskedValue back into yoru I18nCurrencyInput.
setValue(maskedValue)
}, [setValue])
render() {
return (
<I18nCurrencyInput value={value} onChange={this.handleChange}/>
);
}
}
export default MyAppDefault locale is US English with dollars as currency
// $1,234,567.89
<I18nCurrencyInput />A German locale and Euro as the currency
// 1.234.567,89 € (the space is a non-breaking space, i.e. character code 160)
<I18nCurrencyInput locale="de-de" currency="EUR" />Locale and currency with different grouping options
// ₹ 12,34,567.89 (the space is a non-breaking space, i.e. character code 160)
<I18nCurrencyInput locale="en-IN" currency="INR" />Currency without decimals prints just the integer portion
// ¥123,456,789
<I18nCurrencyInput locale="jp-jp" currency="JPY" />You can control whether the user can input negative or positive amounts.
For example, any negative symbols added to the following input will be stripped:
<I18nCurrencyInput requireSign={'positive'} />On the other hand, the following input will always be negative, no matter if the user attempts to remove the negative:
<I18nCurrencyInput forceSign={'negative'} />All other attributes are applied to the input element. For example, you could add a class to the input control
<I18nCurrencyInput className="form-control" />| Option | Default Value | Description |
|---|---|---|
| value | 0 | The initial value |
| locale | "en-us" | locales to use for formatting |
| currency | "USD" | The ISO 4217 currency code for this field |
| currencyDisplay | "symbol" | How you want the currency code to be displayed. See currencyDisplay |
| onChange | n/a | Callback function to handle value changes. Arguments are (maskedValue, value, valueInCents). Corresponds to the value that the user sees ($1,000.00), the value as a number (1000) and the number in the lowest monetary unit (1000000) |
| useGrouping | true | whether to include the integer grouping symbols. For example, in the US, a comma is added every three digits: "1000" is turned into "1,000" |
| requireSign | undefined | 'positive' to turn all non-zero numbers to be positive, 'negative' to make them negative |
| selectAllOnFocus | false | Selects all text on focus or does not |
| inputRef | undefined | a reference created using useRef to access the input element wrapped by I18nCurrencyInput. |
Additionally, I18nCurrencyInput will pass any non-recognized properties down to the input element
This project includes a hook for reusing most of the functionality of I18nCurrencyInput in your own components.
I18nCurrencyInput uses the hook internally and is a good example of its use.
To use useI18nCurrencyInput you would import as follows:
import {useI18nCurrencyInput} from 'react-i18n-currency-input`The properties to useI18nCurrencyInput are similar to the properties in I18nCurrencyInput. The major differences are:
- callbacks, like onChange, onFocus, etc., are ignored. You'll receive your onChange callbacks as the output from the hook.
- you MUST pass an ref to inputRef. It's current value can be undefined or null but the ref has to be passed.
The output of useI18nCurrencyInput are as follows:
| Property | Type | Description |
|---|---|---|
| maskedValue | string | the value that the user sees after formatting, i.e. $1,234.56 - NOTE: Pass this as the value of your input element |
| value | number | the value formatted as a number, i.e. 1234.56 |
| valueInCents | number | the value in the small monetary unit of the currency, i.e. 123456 for $1,234.56 |
| onChange | Function | the change handler to attach to your input element |
| onFocus | Function | the focus handler to attach to your input element |
| onMouseUp | Function | the mouse up handler to attach to your input element |
| onSelect | Function | the select handler to attach to your input element |
react-currency-input is a really great library and most of the code in react-i18n-currency-input is a fairly direct copy from react-currency-input. react-i18n-currency-input would not exist without react-currency-input.
That said, I had one major issue when using react-currency-input: it doesn't use the ECMAScript Internationalization API. The future of the Houdini Project demands we that have a consistent, reliable way to do internationalization of currency amounts. The best way to do so it to use the ECMAScript Internationalization and "outsource" internationalization to a reliable source.
Given this along with the more minor issues of react-currency-input being seemingly unmaintained and not having a Typescript API, it seems like it makes sense to go in a different direction.
- Update the version in package.json, submit a PR and merge into main
- Create a release with a new tag with the version number.
- Use the autofill for the release notes and then edit them so it's a little clearer.
- Mark the release as pre-release if it is
- Publish the release
- The workflows should automatically generate new packages for NPM and the Github Packages