UNPKG

@massds/mayflower-react

Version:

React versions of Mayflower design system UI components

292 lines (291 loc) 12.2 kB
"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;