New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-currency-input

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-currency-input - npm Package Compare versions

Comparing version 1.2.6 to 1.3.0

webpack.config.js

381

lib/index.js

@@ -9,2 +9,8 @@ 'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require('react');

@@ -14,2 +20,6 @@

var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _mask3 = require('./mask.js');

@@ -21,174 +31,273 @@

var CurrencyInput = _react2.default.createClass({
displayName: 'CurrencyInput',
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
/**
* Prop validation.
* @see https://facebook.github.io/react/docs/component-specs.html#proptypes
*/
propTypes: {
onChange: _react.PropTypes.func,
value: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]),
decimalSeparator: _react.PropTypes.string,
thousandSeparator: _react.PropTypes.string,
precision: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]),
inputType: _react.PropTypes.string,
allowNegative: _react.PropTypes.bool,
allowEmpty: _react.PropTypes.bool,
prefix: _react.PropTypes.string,
suffix: _react.PropTypes.string
},
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
// IE* parseFloat polyfill
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseFloat#Polyfill
Number.parseFloat = parseFloat;
var CurrencyInput = function (_Component) {
_inherits(CurrencyInput, _Component);
function CurrencyInput(props) {
_classCallCheck(this, CurrencyInput);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(CurrencyInput).call(this, props));
_this.prepareProps = _this.prepareProps.bind(_this);
_this.handleChange = _this.handleChange.bind(_this);
_this.state = _this.prepareProps(_this.props);
return _this;
}
/**
* Component lifecycle function.
* Exposes the current masked value.
*
* Invoked once and cached when the class is created. Values in the mapping will be set on this.props if that
* prop is not specified by the parent component
*
* @see https://facebook.github.io/react/docs/component-specs.html#getdefaultprops
* @returns {String}
*/
getDefaultProps: function getDefaultProps() {
return {
onChange: function onChange(maskValue, value, event) {/*no-op*/},
value: '0',
decimalSeparator: '.',
thousandSeparator: ',',
precision: '2',
inputType: 'text',
allowNegative: false,
prefix: '',
suffix: ''
};
},
/**
* General function used to cleanup and define the final props used for rendering
* @returns {{ maskedValue: {String}, value: {Number}, customProps: {Object} }}
*/
prepareProps: function prepareProps(props) {
var customProps = _extends({}, props); // babeljs converts to Object.assign, then polyfills.
delete customProps.onChange;
delete customProps.value;
delete customProps.decimalSeparator;
delete customProps.thousandSeparator;
delete customProps.precision;
delete customProps.inputType;
delete customProps.allowNegative;
delete customProps.allowEmpty;
delete customProps.prefix;
delete customProps.suffix;
_createClass(CurrencyInput, [{
key: 'getMaskedValue',
value: function getMaskedValue() {
return this.state.maskedValue;
}
var initialValue = props.value;
if (!initialValue) {
initialValue = props.allowEmpty ? null : '';
} else {
/**
* General function used to cleanup and define the final props used for rendering
* @returns {{ maskedValue: {String}, value: {Number}, customProps: {Object} }}
*/
if (typeof initialValue == 'string') {
// Some people, when confronted with a problem, think "I know, I'll use regular expressions."
// Now they have two problems.
}, {
key: 'prepareProps',
value: function prepareProps(props) {
var customProps = _extends({}, props); // babeljs converts to Object.assign, then polyfills.
delete customProps.onChange;
delete customProps.value;
delete customProps.decimalSeparator;
delete customProps.thousandSeparator;
delete customProps.precision;
delete customProps.inputType;
delete customProps.allowNegative;
delete customProps.allowEmpty;
delete customProps.prefix;
delete customProps.suffix;
// Strip out thousand separators, prefix, and suffix, etc.
if (props.thousandSeparator === ".") {
// special handle the . thousand separator
initialValue = initialValue.replace(/\./g, '');
}
var initialValue = props.value;
if (initialValue === null) {
initialValue = props.allowEmpty ? null : '';
} else {
if (props.decimalSeparator != ".") {
// fix the decimal separator
initialValue = initialValue.replace(new RegExp(props.decimalSeparator, 'g'), '.');
if (typeof initialValue == 'string') {
// Some people, when confronted with a problem, think "I know, I'll use regular expressions."
// Now they have two problems.
// Strip out thousand separators, prefix, and suffix, etc.
if (props.thousandSeparator === ".") {
// special handle the . thousand separator
initialValue = initialValue.replace(/\./g, '');
}
if (props.decimalSeparator != ".") {
// fix the decimal separator
initialValue = initialValue.replace(new RegExp(props.decimalSeparator, 'g'), '.');
}
//Strip out anything that is not a digit, -, or decimal separator
initialValue = initialValue.replace(/[^0-9-.]/g, '');
// now we can parse.
initialValue = Number.parseFloat(initialValue);
}
initialValue = Number(initialValue).toLocaleString(undefined, {
style: 'decimal',
minimumFractionDigits: props.precision,
maximumFractionDigits: props.precision
});
}
//Strip out anything that is not a digit, -, or decimal separator
initialValue = initialValue.replace(/[^0-9-.]/g, '');
var _mask = (0, _mask4.default)(initialValue, props.precision, props.decimalSeparator, props.thousandSeparator, props.allowNegative, props.prefix, props.suffix);
// now we can parse.
initialValue = Number.parseFloat(initialValue);
var maskedValue = _mask.maskedValue;
var value = _mask.value;
return { maskedValue: maskedValue, value: value, customProps: customProps };
}
/**
* Component lifecycle function.
* Invoked when a component is receiving new props. This method is not called for the initial render.
*
* @param nextProps
* @see https://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops
*/
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
this.setState(this.prepareProps(nextProps));
}
/**
* Component lifecycle function.
* @returns {XML}
* @see https://facebook.github.io/react/docs/react-component.html#componentdidmount
*/
}, {
key: 'componentDidMount',
value: function componentDidMount() {
var node = _reactDom2.default.findDOMNode(this.theInput);
var selectionEnd = Math.min(node.selectionEnd, this.theInput.value.length - this.props.suffix.length);
var selectionStart = Math.min(node.selectionStart, selectionEnd);
//console.log("normal", selectionStart, selectionEnd);
node.setSelectionRange(selectionStart, selectionEnd);
}
/**
* Component lifecycle function.
* @returns {XML}
* @see https://facebook.github.io/react/docs/react-component.html#componentdidupdate
*/
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps, prevState) {
var node = _reactDom2.default.findDOMNode(this.theInput);
var selectionEnd = Math.min(this.state.selectionEnd, this.theInput.value.length - this.props.suffix.length);
var selectionStart = Math.min(this.state.selectionStart, selectionEnd);
// moves the cursor to the right when digits are added.
var adjustment = Math.max(this.state.maskedValue.length - prevState.maskedValue.length - 1, 0);
var baselength = this.props.suffix.length + this.props.prefix.length + this.props.decimalSeparator.length + Number(this.props.precision) + 1; // This is to account for the default '0' value that comes before the decimal separator
if (this.state.maskedValue.length == baselength) {
// if we are already at base length, position the cursor at the end.
selectionEnd = this.theInput.value.length - this.props.suffix.length;
selectionStart = selectionEnd;
adjustment = 0;
}
initialValue = Number(initialValue).toLocaleString(undefined, {
style: 'decimal',
minimumFractionDigits: props.precision,
maximumFractionDigits: props.precision
});
node.setSelectionRange(selectionStart + adjustment, selectionEnd + adjustment);
}
var _mask = (0, _mask4.default)(initialValue, props.precision, props.decimalSeparator, props.thousandSeparator, props.allowNegative, props.prefix, props.suffix);
/**
* onChange Event Handler
* @param event
*/
var maskedValue = _mask.maskedValue;
var value = _mask.value;
}, {
key: 'handleChange',
value: function handleChange(event) {
var _this2 = this;
event.preventDefault();
return { maskedValue: maskedValue, value: value, customProps: customProps };
},
var _mask2 = (0, _mask4.default)(event.target.value, this.props.precision, this.props.decimalSeparator, this.props.thousandSeparator, this.props.allowNegative, this.props.prefix, this.props.suffix);
var maskedValue = _mask2.maskedValue;
var value = _mask2.value;
/**
* Component lifecycle function.
* Invoked once before the component is mounted. The return value will be used as the initial value of this.state
*
* @returns {{ maskedValue: {String}, value: {Number}, customProps: {Object} }}
* @see https://facebook.github.io/react/docs/component-specs.html#getinitialstate
*/
getInitialState: function getInitialState() {
return this.prepareProps(this.props);
},
var node = _reactDom2.default.findDOMNode(this.theInput);
var selectionEnd = Math.min(node.selectionEnd, this.theInput.value.length - this.props.suffix.length);
var selectionStart = Math.min(node.selectionStart, selectionEnd);
/**
* Component lifecycle function.
* Invoked when a component is receiving new props. This method is not called for the initial render.
*
* @param nextProps
* @see https://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops
*/
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
this.setState(this.prepareProps(nextProps));
},
event.persist(); // fixes issue #23
this.setState({ maskedValue: maskedValue, value: value }, function () {
_this2.props.onChange(maskedValue, value, event);
_this2.props.onChangeEvent(event, maskedValue, value);
});
}
/**
* Exposes the current masked value.
*
* @returns {String}
*/
getMaskedValue: function getMaskedValue() {
return this.state.maskedValue;
},
/**
* onFocus Event Handler
* @param event
*/
}, {
key: 'handleFocus',
value: function handleFocus(event) {
//Whenever we receive focus check to see if the position is before the suffix, if not, move it.
var selectionEnd = this.theInput.value.length - this.props.suffix.length;
var selectionStart = this.props.prefix.length;
console.log(selectionStart, selectionEnd);
event.target.setSelectionRange(selectionStart, selectionEnd);
this.setState({ selectionStart: selectionStart, selectionEnd: selectionEnd });
}
}, {
key: 'handleBlur',
value: function handleBlur(event) {
this.setState({
selectionStart: null,
selectionEnd: null
});
}
/**
* onChange Event Handler
* @param event
*/
handleChange: function handleChange(event) {
var _this = this;
/**
* Component lifecycle function.
* @returns {XML}
* @see https://facebook.github.io/react/docs/component-specs.html#render
*/
event.preventDefault();
}, {
key: 'render',
value: function render() {
var _this3 = this;
var _mask2 = (0, _mask4.default)(event.target.value, this.props.precision, this.props.decimalSeparator, this.props.thousandSeparator, this.props.allowNegative, this.props.prefix, this.props.suffix);
return _react2.default.createElement('input', _extends({
ref: function ref(input) {
_this3.theInput = input;
},
type: this.props.inputType,
value: this.state.maskedValue,
onChange: this.handleChange,
onFocus: this.handleFocus,
onMouseUp: this.handleFocus
}, this.state.customProps));
}
}]);
var maskedValue = _mask2.maskedValue;
var value = _mask2.value;
return CurrencyInput;
}(_react.Component);
this.setState({ maskedValue: maskedValue, value: value }, function () {
_this.props.onChange(maskedValue, value, event);
});
},
/**
* Prop validation.
* @see https://facebook.github.io/react/docs/component-specs.html#proptypes
*/
CurrencyInput.propTypes = {
onChange: _propTypes2.default.func,
value: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.string]),
decimalSeparator: _propTypes2.default.string,
thousandSeparator: _propTypes2.default.string,
precision: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.string]),
inputType: _propTypes2.default.string,
allowNegative: _propTypes2.default.bool,
allowEmpty: _propTypes2.default.bool,
prefix: _propTypes2.default.string,
suffix: _propTypes2.default.string
};
/**
* Component lifecycle function.
* @returns {XML}
* @see https://facebook.github.io/react/docs/component-specs.html#render
*/
render: function render() {
return _react2.default.createElement('input', _extends({
type: this.props.inputType,
value: this.state.maskedValue,
onChange: this.handleChange
}, this.state.customProps));
}
});
CurrencyInput.defaultProps = {
onChange: function onChange(maskValue, value, event) {/*no-op*/},
onChangeEvent: function onChangeEvent(event, maskValue, value) {/*no-op*/},
value: '0',
decimalSeparator: '.',
thousandSeparator: ',',
precision: '2',
inputType: 'text',
allowNegative: false,
prefix: '',
suffix: ''
};
exports.default = CurrencyInput;
{
"name": "react-currency-input",
"version": "1.2.6",
"version": "1.3.0",
"description": "React component for inputing currency amounts",

@@ -13,3 +13,5 @@ "main": "lib/index.js",

"build-example": "browserify example/example.js -o example/bundle.js -t [ babelify --presets [ es2015 react ] ]",
"test": "mocha --compilers js:babel-register "
"test": "mocha --compilers js:babel-register ",
"webpack": "webpack",
"webpack-dev": "webpack-dev-server"
},

@@ -36,6 +38,9 @@ "repository": {

"dependencies": {
"react": ">=0.14.0 || >=15.0.0"
"react": "^15.5.0",
"react-dom": "^15.5.0",
"prop-types": "^15.5.0"
},
"devDependencies": {
"babel-cli": "^6.18.0",
"babel-loader": "6.4.0",
"babel-preset-es2015": "^6.9.0",

@@ -51,2 +56,3 @@ "babel-preset-react": "^6.5.0",

"mocha": "^2.5.3",
"prop-types": "^15.5.9",
"react-addons-test-utils": "^15.1.0",

@@ -56,4 +62,6 @@ "react-dom": "^15.1.0",

"sinon": "^1.17.4",
"sinon-chai": "^2.8.0"
"sinon-chai": "^2.8.0",
"webpack": "2.2.1",
"webpack-dev-server": "2.4.1"
}
}

@@ -8,2 +8,12 @@ # react-currency-input

## Changes
V1.3.0:
-------
* Depecrated "onChange" option in favor of "onChangeEvent". This fixes the argument order to better match React's default input handling
* Updated dependencies to React 15
* Added parseFloat polyfill
* Persist events to deal with an issue of event pooling
* Other bug fixes.
## Installation

@@ -28,4 +38,4 @@ ```

handleChange(newValue){
this.setState({amount: newValue});
handleChange(event, maskedvalue, floatvalue){
this.setState({amount: maskedvalue});
},

@@ -35,7 +45,7 @@ render() {

<div>
<CurrencyInput value={this.state.amount} onChange={this.handleChange}/>
<CurrencyInput value={this.state.amount} onChangeEvent={this.handleChange}/>
</div>
);
}
}
});
export default MyApp

@@ -63,3 +73,3 @@ ```

}
}
});
export default MyApp

@@ -128,3 +138,4 @@ ```

| value | 0 | The initial currency value |
| onChange | n/a | Callback function to handle value changes |
| onChange | n/a | Callback function to handle value changes. Deprecated, use onChangeEvent. |
| onChangeEvent | n/a | Callback function to handle value changes |
| precision | 2 | Number of digits after the decimal separator |

@@ -131,0 +142,0 @@ | decimalSeparator | '.' | The decimal separator |

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc