npm package: @lightweightform/numeric-input
Description: Lightweightform's numeric input
Author: Opensoft
Latest version: 4.13.0

# Numeric input

Framework-agnostic numeric input elements. This library was created after
successive attempts at implementing some numeric input requirements using
multiple libraries for the creation of masked inputs such as
[Inputmask](https://github.com/RobinHerbots/Inputmask) and
[Text Mask](https://github.com/text-mask/text-mask). These libraries offer
generic solutions for the creation of masked inputs; unfortunately, some of our
requirements for numeric inputs do not fit well with the notion of masks. As
such, when attempting to use these libraries we continuously felt the need to
override or patch certain library-imposed behaviours. It was thus simpler to
create a library tailored to our numeric input needs.

This library converts `<input>` elements into numeric inputs which support the
following:

- Numbers have a set number of decimal places (scale) and begin to be written
  from the right-most decimal place, i.e. if the number is set to have a scale
  of `2` and the user types in `1`, the resulting value is `'0.01'`.
- Numbers support an arbitrary number of leading zeroes, i.e. if the number is
  set to have `4` leading zeroes and the user types in `1`, the resulting value
  is `'0001'`.
- The numeric input may represent an integer or a floating number; this means
  that the value `'0.01'` displayed in the input element may represent either
  the number `1` (integer) or the number `0.01` (float). Representing numbers as
  integers removes the risk of floating point errors.
- Numeric inputs may set their minimum and maximum values which are validated as
  appropriate while the user is typing. Out of bound values may still be
  programmatically set on the numeric input.
- A number's signal may be toggled by typing `-` anywhere in the input element.
- Prefixes and suffixes are supported, e.g. specifying a prefix of `'$'` will
  result in the number `0.01` to be formatted as `'$0.01'`; a suffix of `'€'`
  results in `'0.01 €'`.
- The decimal and thousands separators of the numeric input may be specified,
  this means that we may choose to display the number `1234567.89` as
  `'1.234.567,89'` by setting the decimal separator as `','` and the thousands
  separator as `'.'`.
- A number being written is automatically formatted as it is being written and
  the caret position is properly updated.
- Empty values are supported (they represent `null`) and result from deleting
  the whole input element's text or from pressing `Backspace` or `Delete` when
  the numeric input's value is `0`.

## Allowed `<input>` elements

The library will work with inputs of type `text`, `search`, `tel`, and
`password`; unfortunately, the `number` type is not supported. It is currently
recommended to use a type of `text` as the `tel` type forces a virtual keyboard
which, in some devices, does not contain a `-` key. In the future, the
recommended way of forcing a numeric virtual keyboard should be with the
attribute `inputmode` set to `"numeric"`, see:
[Can I use...](https://caniuse.com/#search=inputmode) for browser compatibility.

## Example usage

```js
import { NumericInput } from '@lightweightform/numeric-input';

const inputElement = document.getElementById('some-input-element');
const numericInput = new NumericInput(inputElement, {
  numericRepresentation: 'int',
  scale: 2,
  suffix: ' €',
  decimalSeparator: ',',
  thousandsSeparator: ' ',
});

numericInput.update('1234567');
numericInput.toString(); // `'1 234,67 €'`
numericInput.toNumber(); // `1234567`
```

## API

The `@lightweightform/numeric-input` API is available at:
https://docs.lightweightform.io/api/numeric-input.

## Support

- **Internet Explorer**: 11 (requires a `String.prototype.repeat()` polyfill)
- **Other browsers**: Latest 2 versions

## Limitations

- We use
  [`Number.prototype.toFixed(scale)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed)
  to help format numbers. Most browsers support `scale` up to `100` (maximum
  value the numeric input API allows), however, some browsers only support
  `scale` up to `20` (which is valid according to the spec), so set `scale > 20`
  at your own risk (will throw an exception in unsupported browsers).