@massds/mayflower-react
Version:
React versions of Mayflower design system UI components
292 lines (291 loc) • 12.2 kB
JavaScript
"use strict";
exports.__esModule = true;
exports["default"] = void 0;
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _classnames = _interopRequireDefault(require("classnames"));
var _is = _interopRequireDefault(require("is"));
var _index = _interopRequireDefault(require("../Input/index.js"));
var _error = _interopRequireDefault(require("../Input/error.js"));
var _context = require("../Input/context.js");
var _validate = require("../Input/validate.js");
var _utility = require("../Input/utility.js");
var _componentPropTypeCheck = require("../utilities/componentPropTypeCheck.js");
var _excluded = ["max", "min", "step", "name", "onChange", "onBlur", "placeholder", "width", "maxlength", "showButtons"];
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } /**
* InputNumber module.
* @module @massds/mayflower-react/InputNumber
* @requires module:@massds/mayflower-assets/scss/01-atoms/_input--button
* @requires module:@massds/mayflower-assets/scss/01-atoms/01-atoms/helper-text
* @requires ma__input--button('number');
*/
var NumberInput = function NumberInput(props) {
var ref = /*#__PURE__*/_react["default"].createRef();
var upRef = /*#__PURE__*/_react["default"].createRef();
var downRef = /*#__PURE__*/_react["default"].createRef();
return /*#__PURE__*/_react["default"].createElement(_context.InputContext.Consumer, null, function (context) {
var hasValue = _is["default"].number(context.getValue());
var inputClasses = (0, _classnames["default"])({
'ma__input-number__control': true,
'js-is-required': props.required,
'ma__input-number__control--showButtons': props.showButtons || props.unit && hasValue
});
var unitClasses = (0, _classnames["default"])({
'ma__input-number-unit': true,
'ma__input-number-unit--disabled': props.disabled,
'ma__input-number-unit--showButtons': props.showButtons
});
var displayErrorMessage = function displayErrorMessage(val) {
var min = props.min,
max = props.max,
required = props.required;
if (required && !_is["default"].number(val)) {
var errorMsg = 'Please enter a value.';
return {
showError: true,
errorMsg: errorMsg
};
}
if (_is["default"].number(val)) {
var _validNumber = (0, _validate.validNumber)(val, min, max),
showError = _validNumber.showError,
_errorMsg = _validNumber.errorMsg;
return {
showError: showError,
errorMsg: _errorMsg
};
}
return {
showError: false,
errorMsg: ''
};
};
var hasNumberProperty = function hasNumberProperty(obj, property) {
return Object.prototype.hasOwnProperty.call(obj, property) && _is["default"].number(obj[property]);
};
var handleOnBlur = function handleOnBlur(e) {
e.persist();
var inputEl = ref.current;
var newValue = inputEl.value ? Number(inputEl.value) : inputEl.value;
if (hasNumberProperty(props, 'max') && newValue > props.max) {
newValue = props.max;
}
if (hasNumberProperty(props, 'min') && newValue < props.min) {
newValue = props.min;
}
if (_is["default"].number(newValue)) {
// Since to Fixed returns a string, we have to cast it back to a Number
newValue = Number(newValue.toFixed((0, _utility.countDecimals)(props.step)));
var updateError = displayErrorMessage(newValue);
context.updateState(_extends({
value: newValue
}, updateError), function () {
if (_is["default"].fn(props.onBlur)) {
props.onBlur(e, newValue);
}
});
}
};
var handleChange = function handleChange(e) {
e.persist();
var inputEl = ref.current;
var newValue = inputEl.value ? Number(inputEl.value) : inputEl.value;
var updateError = displayErrorMessage(newValue);
context.updateState(_extends({
value: newValue
}, updateError), function () {
if (_is["default"].fn(props.onChange)) {
props.onChange(e, newValue, props.id);
}
});
};
var handleAdjust = function handleAdjust(e) {
e.persist();
var direction;
if (e.currentTarget === upRef.current) {
direction = 'up';
} else {
direction = 'down';
}
var inputEl = ref.current;
var newValue = inputEl.value ? Number(inputEl.value) : inputEl.value;
if (direction === 'up' && (!hasNumberProperty(props, 'max') || newValue < props.max)) {
// Since to Fixed returns a string, we have to cast it back to a Number
newValue = newValue ? Number((newValue + props.step).toFixed((0, _utility.countDecimals)(props.step))) : props.step;
var updateError = displayErrorMessage(newValue);
context.updateState(_extends({
value: newValue
}, updateError), function () {
if (_is["default"].fn(props.onChange)) {
props.onChange(e, newValue, props.id);
}
});
} else if (direction === 'down' && (!hasNumberProperty(props, 'min') || newValue > props.min)) {
// Since to Fixed returns a string, we have to cast it back to a Number
newValue = newValue ? Number((newValue + props.step * -1).toFixed((0, _utility.countDecimals)(props.step))) : props.step * -1;
var _updateError = displayErrorMessage(newValue);
context.updateState(_extends({
value: newValue
}, _updateError), function () {
if (_is["default"].fn(props.onChange)) {
props.onChange(e, newValue, props.id);
}
});
}
};
var inputAttr = {
className: inputClasses,
name: props.name,
id: props.id,
type: 'number',
placeholder: props.placeholder,
maxLength: Number(props.maxlength),
style: props.width ? {
width: props.width + "px"
} : null,
onChange: handleChange,
onBlur: handleOnBlur,
required: props.required,
disabled: props.disabled,
step: props.step,
ref: ref
};
inputAttr.value = context.getValue();
if (_is["default"].number(props.max)) {
inputAttr.max = props.max;
}
if (_is["default"].number(props.min)) {
inputAttr.min = props.min;
}
return /*#__PURE__*/_react["default"].createElement("div", {
className: "ma__input-number"
}, /*#__PURE__*/_react["default"].createElement("input", inputAttr), props.unit && hasValue ? /*#__PURE__*/_react["default"].createElement("span", {
className: unitClasses
}, props.unit) : null, props.showButtons && /*#__PURE__*/_react["default"].createElement("div", {
className: "ma__input-number__control-buttons"
}, /*#__PURE__*/_react["default"].createElement("button", {
type: "button",
"aria-label": "increase value",
className: "ma__input-number__control-plus",
"data-direction": "up",
onClick: handleAdjust,
disabled: props.disabled,
tabIndex: -1,
ref: upRef
}), /*#__PURE__*/_react["default"].createElement("button", {
type: "button",
"aria-label": "decrease value",
className: "ma__input-number__control-minus",
"data-direction": "down",
onClick: handleAdjust,
disabled: props.disabled,
tabIndex: -1,
ref: downRef
})));
});
};
NumberInput.propTypes = process.env.NODE_ENV !== "production" ? {
required: _propTypes["default"].bool,
showButtons: _propTypes["default"].bool,
unit: _propTypes["default"].string,
disabled: _propTypes["default"].bool,
min: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]),
max: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]),
step: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]),
onBlur: _propTypes["default"].func,
onChange: _propTypes["default"].func,
name: _propTypes["default"].string,
id: _propTypes["default"].string,
maxlength: _propTypes["default"].number,
placeholder: _propTypes["default"].string,
width: _propTypes["default"].number
} : {};
var InputNumber = function InputNumber(props) {
var max = props.max,
min = props.min,
step = props.step,
name = props.name,
onChange = props.onChange,
onBlur = props.onBlur,
placeholder = props.placeholder,
width = props.width,
maxlength = props.maxlength,
showButtons = props.showButtons,
inputProps = _objectWithoutPropertiesLoose(props, _excluded);
// Input and Number share the props.required, props.id and props.disabled values.
var numberProps = {
max: max,
min: min,
step: step,
name: name,
placeholder: placeholder,
width: width,
maxlength: maxlength,
required: props.required,
id: props.id,
onChange: onChange,
onBlur: onBlur,
disabled: props.disabled,
unit: props.unit,
showButtons: showButtons
};
return /*#__PURE__*/_react["default"].createElement(_index["default"], inputProps, /*#__PURE__*/_react["default"].createElement(NumberInput, numberProps), /*#__PURE__*/_react["default"].createElement(_error["default"], {
id: props.id
}));
};
InputNumber.propTypes = process.env.NODE_ENV !== "production" ? {
/** Whether the label should be hidden or not */
hiddenLabel: _propTypes["default"].bool,
/** The label text for the input field, can be a string or a component */
labelText: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].object]).isRequired,
/** Whether the field is required or not */
required: _propTypes["default"].bool,
/** Whether the field is disabled or not */
disabled: _propTypes["default"].bool,
/** The unique ID for the input field */
id: _propTypes["default"].string.isRequired,
/** The name for the input field */
name: _propTypes["default"].string.isRequired,
/** The max acceptable input length */
maxlength: _propTypes["default"].number,
/** The pattern to filter input against, e.g. "[0-9]" for numbers only */
pattern: _propTypes["default"].string,
/** The number of characters wide to make the input field */
width: _propTypes["default"].number,
/** The placeholder text for the input field */
placeholder: _propTypes["default"].string,
/** The message to be displayed in the event of an error. */
errorMsg: _propTypes["default"].string,
/** Custom change function */
onChange: _propTypes["default"].func,
/** Custom onBlur function */
onBlur: _propTypes["default"].func,
/** Default input value */
defaultValue: _propTypes["default"].number,
/** Max value for the field. */
max: _propTypes["default"].number,
/** Min value for the field. */
min: _propTypes["default"].number,
/** Using the up/down arrow keys will increment/decrement the input value by this number. */
step: _propTypes["default"].number,
/** Inline label and input field */
inline: _propTypes["default"].bool,
/** A unit that is a string of no more than 2 characters renders in the input after the value, e.g. % */
unit: function unit(props, propName) {
return (0, _componentPropTypeCheck.numberCharacterPropTypeCheck)(props, propName, 2);
},
/** Whether to render up/down buttons */
showButtons: _propTypes["default"].bool
} : {};
InputNumber.defaultProps = {
hiddenLabel: false,
required: false,
onChange: null,
step: 1,
showButtons: true,
unit: ''
};
var _default = exports["default"] = InputNumber;
module.exports = exports.default;