Giter Site home page Giter Site logo

react-currency-input-field's Introduction

React Currency Input Field Component

npm npm NPM Codecov Coverage Release build

Features

  • Allows abbreviations eg. 1k = 1,000 2.5m = 2,500,000
  • Prefix and Suffix options eg. £ or $
  • Automatically inserts group separator
  • Accepts Intl locale config
  • Can use arrow down/up to step
  • Can allow/disallow decimals
  • Written in TypeScript and has type support
  • Does not use any third party packages

Examples

Play with demo or view examples code

React Currency Input Demo

Install

npm install react-currency-input-field

or

yarn add react-currency-input-field

Usage

import CurrencyInput from 'react-currency-input-field';

<CurrencyInput
  id="input-example"
  name="input-name"
  placeholder="Please enter a number"
  defaultValue={1000}
  decimalsLimit={2}
  onValueChange={(value, name, values) => console.log(value, name, values)}
/>;

Have a look in src/examples for more examples on implementing and validation.

Props

Name Type Default Description
allowDecimals boolean true Allow decimals
allowNegativeValue boolean true Allow user to enter negative value
defaultValue number Default value
value number Programmatically set the value
onValueChange function Handle change in value
placeholder string Placeholder if no value
decimalsLimit number 2 Limit length of decimals allowed
decimalScale number Specify decimal scale for padding/trimming eg. 1.5 -> 1.50 or 1.234 -> 1.23 if decimal scale 2
fixedDecimalLength number Value will always have the specified length of decimals
prefix string Include a prefix eg. £ or $
suffix string Include a suffix eg. € or %
decimalSeparator string locale default Separator between integer part and fractional part of value
groupSeparator string locale default Separator between thousand, million and billion
intlConfig object International locale config
disabled boolean false Disabled
disableAbbreviations boolean false Disable abbreviations eg. 1k -> 1,000, 2m -> 2,000,000
disableGroupSeparators boolean false Disable auto adding the group separator between values, eg. 1000 -> 1,000
maxLength number Maximum characters the user can enter
step number Incremental value change on arrow down and arrow up key press
transformRawValue function Transform the raw value from the input before parsing. Needs to return string.

onValueChange

Handle changes to the value.

onValueChange = (value, name, values) => void;

value

value will give you the value in a string format, without the prefix/suffix/separators.

Example: £123,456 -> 123456

name

name is the name you have passed to your component

values

values gives an object with three key values:

  • float: Value as float or null if empty. Example: "1.99" > 1.99
  • formatted: Value after applying formatting. Example: "1000000" > "1,000,0000"
  • value: Non formatted value as string, ie. same as first param.

Abbreviations

It can parse values with abbreviations k, m and b

Examples:

  • 1k = 1,000
  • 2.5m = 2,500,000
  • 3.456B = 3,456,000,000

This can be turned off by passing in disableAbbreviations.

Prefix and Suffix

You can add a prefix or suffix by passing in prefix or suffix.

import CurrencyInput from 'react-currency-input-field';

<CurrencyInput prefix="£" value={123} />;
// £123

<CurrencyInput suffix="%" value={456} />;
// 456%

Note: Passing in prefix/suffix will override the intl locale config.

Separators

You can change the decimal and group separators by passing in decimalSeparator and groupSeparator.

Example:

import CurrencyInput from 'react-currency-input-field';

<CurrencyInput decimalSeparator="," groupSeparator="." />;

Note: the separators cannot be a number, and decimalSeparator must be different to groupSeparator.

To turn off auto adding the group separator, add disableGroupSeparators={true}.

Intl Locale Config

This component can also accept international locale config to format the currency to locale setting.

Examples:

import CurrencyInput from 'react-currency-input-field';

<CurrencyInput intlConfig={{ locale: 'en-US', currency: 'GBP' }} />;

<CurrencyInput intlConfig={{ locale: 'ja-JP', currency: 'JPY' }} />;

<CurrencyInput intlConfig={{ locale: 'en-IN', currency: 'INR' }} />;

locale should be a BCP 47 language tag, such as "en-US" or "en-IN".

currency should be a ISO 4217 currency code, such as "USD" for the US dollar, "EUR" for the euro, or "CNY" for the Chinese RMB.

Any prefix, suffix, group separator and decimal separator options passed in will override the default locale settings.

Decimal Scale and Decimals Limit

decimalsLimit and decimalScale sound similar but have different usages.

decimalsLimit prevents the user from typing more than the limit, and decimalScale will format the decimals onBlur to the specified length, padding or trimming as necessary.

Example:

If decimalScale is 2

- 1.5 becomes 1.50 (padded)
- 1.234 becomes 1.23 (trimmed)

---

If decimalLimit is 2

- User enters 1.23
- User is then prevented from entering another value

Fixed Decimal Length

Use fixedDecimalLength so that the value will always have the specified length of decimals.

This formatting happens onBlur.

Example if fixedDecimalLength was 2:

- 1 -> 1.00
- 123 -> 1.23
- 12.3 -> 12.30
- 12.34 -> 12.34

Format values for display

Use the formatValue function to format the values to a more user friendly string. This is useful if you are displaying the value somewhere else ie. the total of multiple inputs.

import { formatValue } from 'react-currency-input-field';

// Format using prefix, groupSeparator and decimalSeparator
const formattedValue1 = formatValue({
  value: '123456',
  groupSeparator: ',',
  decimalSeparator: '.',
  prefix: '$',
});

console.log(formattedValue1);
// $123,456

// Format using intl locale config
const formattedValue2 = formatValue({
  value: '500000',
  intlConfig: { locale: 'en-IN', currency: 'INR' },
});

console.log(formattedValue2);
// ₹5,00,000

v3.0.0 Release Notes

Breaking Changes

  • ⚠️ onChange renamed to onValueChange ⚠️
  • onBlurValue has been removed.
  • turnOffAbbreviations renamed to disableAbbreviations.
  • turnOffSeparators renamed to disableGroupSeparators.
  • precision renamed to decimalScale

Improvements in v3

  • Intl locale config can be passed in. Please note: formatting where the currency symbol is placed after the value like a suffix eg. (1 234,56 €) might cause problems, this is still in development.
  • Group separator will default to browser locale if not specified.
  • Can pass ref to the component.
  • onChange and onBlur functions can be passed in and will be called with original event.

Reasoning

As this component grew in usage, I started getting more bug reports and feature requests. That wasn't a problem though, because I was always happy to fix any bugs and implement any features if I could.

However, this meant sometimes I was a bit trigger happy, and didn't always think about how the different options interacted with each other. I found that it was getting a bit convoluted for my liking, and choices I had made earlier in development, now seemed like it could be improved.

Therefore, I took the opportunity of v3 to do a bit of tidying up for the component, in order to make it more future proof and intuitive to use.

I apologize if any of the changes cause new bugs or issues. Please let me know and I will fix asap.

Issues

Feel free to raise an issue on Github if you find a bug or have a feature request.

Contributing

If you want to contribute to this repository, please refer to the contributing doc.

react-currency-input-field's People

Contributors

aconrad avatar adamsoutar avatar cchanxzy avatar contraboi avatar danielcardoso5 avatar dependabot[bot] avatar ferreiraraphael avatar georgesmith46 avatar ivan-dalmet avatar jefelewis avatar krot47 avatar marcoromag avatar max-sym avatar mpsijm avatar ng185115 avatar osdiab avatar polarstoat avatar raddishiow avatar semantic-release-bot avatar sienic avatar simonpkerr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

react-currency-input-field's Issues

Can't set a min and max values

Hi, Great work on the library, love it!

I would love to be able to set a min and max value that can't be crossed, is it currently available? else are you willing to add support to it?

support for fixed decimals?

Hi there! I'm currently using https://www.npmjs.com/package/react-currency-input .. which is great on desktop, but is terrible on mobile.

I just saw this relatively new project here when I went to look to see if anyone has created an alternative to the above one... so I thought I'd ask for the feature that I need most: fixed decimal length inputs. My currency inputs should always have 2 decimals, so working in USD, entering "342" should give you "$3.42" in the output display, and should return the value of the input in decimal numbers (cents)

I haven't yet looked through this source code, to see how easy it would be to modify it, or to wrap it with another component that might do that .. just thought I'd throw the idea out here, and see if you'd be interested in supporting some additional user scenarios.

Custom component support

Hi, great package! It would be good if we could add custom component support.

I will submit a pull request, but forgive me... my TS knowledge is limited 😬

Deletion does not work if there is a suffix with intlConfig configuration

Hi, I ran into a terrible problem! I want to customize the input of numbers into the input using intlConfig lacquerization, but after entering the value, it is not deleted if there is a suffix, but especially if this type is US$, please tell me, do you plan to fix this problem in the near future? So I don't want to look for an alternative, your code is perfect for my implementation.

P.S. Thanks for making a cool feature!

safari focus of input

just a little one...
when viewing the demo page in safari, one of the currency inputs focuses automatically. ideally this shouldn't happen.
We've noticed this in some implementations where we've used currency input.

Screenshot 2021-01-19 at 14 26 57

DecimalScale property adds padding when there is no decimal

Hello,

I was using this library and found that the Decimal Scale Property is padding any value I add into the currency input even if the user has not entered a decimal point.

image

Code below:

      <CurrencyInput
        name={name}
        placeholder="Enter Value"
        decimalsLimit={2}
        decimalScale={2}
        onValueChange={(value: string | undefined) => {
          if (value === undefined) value = "0";
          setFieldValue(name, parseFloat(value));
        }}
      />

Note I am using formik here.

My understanding of this feature was that padding or trimming only occur when the user has added a decimal point which is why it is distinct from fixedDecimalLength property.

Can't clear the whole input

I installed the package and used the example in the guide. Everthing is working fine, but when I try to clear the input using backspace key, all charaters get deleted, exept for the last one.

  <CurrencyInput
    id="input-example"
    name="input-name"
    placeholder="£1,000"
    defaultValue={1000}
    allowDecimals={true}
    decimalsLimit={2}.
    prefix="$"
  />

Screenshot (2)

This package specifies a 'main' module field that could not be resolved

Hi, I am trying to install the plugin via

npm install react-currency-input-field

and then use the example provided in the readme:

<CurrencyInput id="input-example" name="input-name" placeholder="Please enter a number" defaultValue={1000} decimalsLimit={2} onValueChange={(value, name) => console.log(value, name)} />;

This yields the following error:

While trying to resolve module react-currency-input-field from file /Users/xxx/xxx/xxx/src/screens/authorised/create/OddsPicker.js, the package /Users/xxx/xxx/xxx/node_modules/react-currency-input-field/package.json was successfully found. However, this package itself specifies a main module field that could not be resolved (/Users/xxx/xxx/xxx/node_modules/react-currency-input-field/dist/index.js. Indeed, none of these files exist:

Version:
Expo: 40.0.0
React: 16.13.1
React-Native: 0.63.4
react-currency-input-field: 3.0.3

Anything glaringly obvious that I am missing? Perhaps and expo issue?

Intl.NumberFormat.formatToParts() not supported on iOS <13

I'm hitting a problem when trying to use formatValue on iOS ~12:
Intl.NumberFormat.formatToParts() is not supported...
Is there a way of pollyfilling this?

If not, I'll have to go back to using numbro for formatting display values...

Why does this keep adding different numbers?

For an example add a 9 to this 999999999999999 and it will be converted to 10,000,000,000,000,000, even adding very long numbers get changed, this isn't great for a web app dealing with money...

I can't see any docs revealing why this is happening or how to stop it, tried decimalScale={undefined}, nothig changed...

Please, help

Can't insert decimal separator same as group separator

When we have default group separator set as comma (,) we can't insert comma as decimal separator. It looks obvious but there is an issue when you have for example UK keyboard on your phone. Since we have inputmode set to decimal we can't insert any other decimal separator than this comma and in general we can't set any price with decimals in this configuration.
It might be a general case when we have USD but the user is from UK and can't provide any price and in USA there is comma as thousands separator.
This issue occur on iPhone with English UK, when I had polish language there were . and , to pick so it was ok but for English UK there is only , to pick.

The plugin keeps putting 'NaN' in its value

Hi guys, I just installed the plugin ('^ 3.3.1').

And I am facing a problem with my input. When I enter 10, for example, the value of the input changes to 'NaN' and that's it.

Code

import CurrencyInput from 'react-currency-input-field';

<CurrencyInput
    className="ant-input"
    allowDecimals={true}
    allowNegativeValue={false}
    decimalsLimit={2}
    intlConfig={{ locale: 'pt-br', currency: 'BRL' }}
/>

Print and Gif

image

Gif

Whitespace or empty string is considered a number, thus unusable as group separator

As the title says, currently the component throws when using either a blank string or a whitespace as group separator.

Whitespace actually is a correct separator in certain languages, so allowing this should be a must.
As for an empty string, this could be handy if the developer doesn't want any separator shown (I suppose turnOffSeparators already does this though).

Feature Request: Force decimal places on blur.

Very nice control. I do have a feature request that would round it out a bit.

Example: I enter 123 (without decimal places) and I leave the input (onBlur), the field formats to 123.00
Or I enter: 123.1 and onBlur it formats to 123.10

Suggested usage: <CurrencyInput formatDecimals="2" ..... >

Cursor jumps 2 places to the left when entering a decimal point

Select the current value and start entering a new value. When you enter a decimal point to (in order to enter the 2 decimals), the input cursor jumps 2 places to the left (which of course is unexpected and causes you to enter something different than what you had intended).

Defining onBlur overrides component formatting

Hi, so I was trying that library and it seems great. The only weird thing is that, when I define my own onBlur prop, it ends up overriding the CurrencyInput one.

While looking at the code, I noticed you are merging the onChange prop with yours, but not the onBlur one. Would it be possible to have a custom onBlur prop while keeping your formatting functionailities? I need to do something with the value and blur and end up losing the formatting functionnality.

unable to empty the input

Hi, I'm having a problem while trying to empty the input using backspace.
After I get to the last number I'm unable to delete it or set to 0 easily.
For example I if the value is 20 and I want to delete it using backspace I get an undeletable 2, if now I want to set it to 0 I have to write 20 and then using the arrow keys move and delete the number 2.

I think that would improve greatly the UX if when I delete every number I get a 0 in the input

Entering negative values not working as expected

Hi,
On mount of the CurrencyInput component, when I try to enter a negative value, as soon as I enter '-', the cursor always resets to the start of the input, on further entering numbers, the '-' disappears from the start.
This issue occurs with and without prefix and only on the first mount when there is no defaultValue or value is empty/undefined. Once you clear the input field, it works as expected. Please refer to the video attached.

simplescreenrecorder-2021-01-31_19.42.56.mp4

Codesandbox link:
https://codesandbox.io/s/staging-bird-8syt2?file=/src/App.js

Ability to disable negative values

I know recently there was a feature pushed to support negative values.

It would be great to have a prop to allowNegativeValue={bool}

This is not something we want to support by default in our application.

Thank you.

TypeError: r.slice is not a function

I'm getting a "TypeError: r.slice is not a function" when trying to format a value using formatValue

() => {
  const value = jobsArray.sum('fare')
  return formatValue({ value: value, intlConfig: { locale: 'en-GB', currency: 'GBP' } })
}

When value === 0
I don't think it's an issue with the value?

jobsArray.sum() is defined as:

sum (key: string): number {
    return this.reduce((a, b) => a + (parseFloat(b[key]) || 0), 0)
  }

abbreviation values

Hi, first thanks for the great package, very useful. I just noticed though that you can input any of the abbreviations as the first character, without a value. is this a known issue? It'd also be nice to be able to disable abbreviations like you can with separators etc.

Screenshot 2020-11-18 at 13 32 41

Do not allow whitespace at the start of the input value

Hello, I cannot find a way to prevent whitespace at the start of the input.
I've attached a screenshot below. This also happens in the demos that have so graciously been set up. I've added some handling to prevent whitespace but it only works when there are existing numbers in my input value already. Even when the value from the onChange === "", the input will still render those spaces. Can someone help me out with this.
Screen Shot 2020-08-10 at 3 40 55 PM

onTipValueChange = (value) => {
    if (value !== undefined) value = value.replace(/\s/g, "");
    if (value === undefined || !Number.isNaN(Number(value))) {
      this.setState({ customTip: value });
    }
};
<CurrencyInput
            id="custom-tip"
            name="custom-tip"
            placeholder="$0.00"
            value={this.state.customTip}
            allowDecimals={true}
            decimalsLimit={2}
            maxLength={8}
            prefix={"$"}
            onChange={this.onTipValueChange}
            onBlur={() => {}}
 />

Prefix Returns NAN

for some reason if I add prefix JMD I get a NAN value displayed it was working fine a few months ago.

Support for Euro notation

Hey! Is there a way to use the correct notation for Euro?
In Euro countries (at least for the most part of them) amounts should have commas to divide decimals from the integer part of the number and points to separate thousands (ex. € 100.000.000,00 instead of £ 100,000,000.00).
Thanks

Support for negative dollar amounts

Hi,

Is it possible to add support for negative dollar amounts such as -$20.00 or (20.00) ?

I haven't checked to see how hard it would be to implement but it would be much appreciated

HTML 5 Validation

Hi, I've put the currency field inside a Form, when i try to submit it it fires the HTML 5 Validation, the pattern of the field accpet only number but with the currency prefix it says that I'm not respecting the correct format

Get event when calling the onChange function

It would be great if the onChange function would provide the event that gets triggered like the default onChange function in react does. The event type should be React.ChangeEvent<HTMLInputElement>

pre-filled value

how to apply default value for this input and allow decimalLimit.

eg. $ 12,000.75

Unexpected cursor movement

When playing with your component, I noticed some issues with the cursor's position

The below gif's typing sequences is 123456789{left}{left}{left}{delete}{delete}

Kapture 2021-03-31 at 17 22 37

I would either expect the first {delete} to move the cursor over the groupSeparator or to delete the number preceding it. I certainly don't expect my cursor to jump all the way to the end of the input value.

Hope this helps!

It is not accepting disabled prop

<CurrencyInput value={1000} name="input" className=" curr-text-box" allowDecimals={false} onChange={this.updateInputField} disabled={true} />

Decimal Scale not trimming as expected

This is a great package and easy to use, however, the trimming isn't working as I expect it would.

I'm using the formatValue function to trim to 2 decimal places which I'd expect it to do even if I'm dividing the value by a decimal value. However, when I do that I get the full length of the value with all the decimal places.

Am I using it incorrectly? Could you let me know if I'm missing something. Thanks!

Below is a test component. I'm just dividing the value by a decimal as an example. It has the same effect and even the input doesn't trim to two decimal

import React, { useState } from 'react'
import CurrencyInput from 'react-currency-input-field'
import { Col, Container, Form, Row } from 'react-bootstrap'

export default function Home() {
  const [testCurrency, setTestCurrency] = useState<any>()

  function handleChange(value: any, name: any) {
    console.log(value, name)
    setTestCurrency(Number.parseFloat(value) / 0.33)
  }
function roundToTwoDecimals(stringedNumber: string): string {
  return formatValue({
    value: stringedNumber,
    decimalSeparator: '.',
    groupSeparator: ',',
    decimalScale: 2,
    intlConfig: { locale: 'en-AU', currency: 'AUD' }
  })
  return (
    <main>
      <Container>
        <p>Home</p>
        <Form.Group as={Row}>
          <Form.Label className="mt-2">
            <h5>Test Currency</h5>
          </Form.Label>
          <Col>
            <Form.Control
              as="input"
              name="testCurrency"
              value={roundToTwoDecimals(`${testCurrency || 0}`)}
              readOnly
              plaintext
            />
          </Col>
          <CurrencyInput
            className="form-control"
            name="testCurrency"
            intlConfig={{ locale: 'en-AU', currency: 'AUD' }}
            decimalScale={2}
            allowNegativeValue={false}
            value={testCurrency}
            onValueChange={handleChange}
          />
        </Form.Group>
      </Container>
    </main>
  )
}

$ as prefix causes unexpected results.

Using $ as the prefix (a fairly common use case) causes unexpected behaviour.

To Reproduce:

  • Change line 7 in Example 1 from const prefix = "£"; to const prefix = "$";

Unexpected Behaviour 1:

  • Type in 5.55 into the input
  • Expected Output: $5.55
  • Actual Output: $.55

Unexpected Behaviour 2:

  • Type in 100 into the input
  • Unfocus input (cents added as expected)
  • Focus and unfocus again
  • Expected Output: $100.00
  • Actual Output: $1.00

I suspect the reason may be related to the regex

const [prefixWithValue, preValue] = RegExp(`(\\d+)-?${prefix}`).exec(value) || [];

Where ${prefix} must be escaped.

I plan on submitting a PR later today.

Thanks. 😄

Voice Over Accessibility Issue

Something weird happens while using voiceover and you type in numbers that go into the thousands. It looks like the voice over ignores the first number of the sequence.

image

To recreate:

  1. Set up a simple field or use one from the examples
  2. Start a voice over session
  3. Type a number longer than 3 digits

fixedDecimalLength on Load

Hi! Thank you for the nice currency input component, very handy.

For my use case, fixedDecimalLength only being applied onBlur becomes a problem. All of my values come from the server in cents, and when in edit mode, I'd like to start off by displaying them in the correct format (divided by 100 with two decimals). However, they appear without the decimals until they're clicked and then blurred. Any work around this?

Thanks!

Evan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.