UNPKG

@chayns-components/core

Version:

A set of beautiful React components for developing your own applications with chayns.

257 lines (254 loc) • 9.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = require("motion/react"); var _react2 = _interopRequireWildcard(require("react")); var _amountControl = require("../../utils/amountControl"); var _useKeyboardFocusHighlighting = require("../../hooks/useKeyboardFocusHighlighting"); var _Icon = _interopRequireDefault(require("../icon/Icon")); var _AmountControl = require("./AmountControl.styles"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const AmountControl = ({ amount, icon, iconColor, isDisabled = false, label, maxAmount, minAmount = 0, onChange, shouldEnableKeyboardHighlighting, shouldForceLabel = false, shouldShowAddIconOnMinAmount = false, shouldShowIcon = true, shouldShowWideInput = false, step: stepProp = 1 }) => { const shouldShowKeyboardHighlighting = (0, _useKeyboardFocusHighlighting.useKeyboardFocusHighlighting)(shouldEnableKeyboardHighlighting && !isDisabled); const [amountValue, setAmountValue] = (0, _react2.useState)(minAmount); const [inputValue, setInputValue] = (0, _react2.useState)(minAmount.toString()); const [displayState, setDisplayState] = (0, _react2.useState)('default'); const [isEditing, setIsEditing] = (0, _react2.useState)(false); const step = (0, _react2.useMemo)(() => Number.isSafeInteger(stepProp) && stepProp >= 1 ? stepProp : 1, [stepProp]); const inputRef = (0, _react2.useRef)(null); /** * This function controls the displayState */ (0, _react2.useEffect)(() => { switch (true) { case maxAmount && amountValue >= maxAmount: setDisplayState('maxAmount'); return; case amountValue > minAmount: setDisplayState('normal'); return; case amountValue === minAmount && amountValue >= 0 && shouldShowAddIconOnMinAmount: setDisplayState('minAmount'); return; default: setDisplayState('default'); } }, [amountValue, maxAmount, minAmount, shouldShowAddIconOnMinAmount]); const hasFocus = (0, _react2.useMemo)(() => displayState !== 'default', [displayState]); /** * Function that sets the amountValue to the amount */ (0, _react2.useEffect)(() => { if (typeof amount !== 'number') { return; } setAmountValue((0, _amountControl.checkForValidAmount)({ amount, maxAmount, minAmount })); setInputValue((0, _amountControl.checkForValidAmount)({ amount, maxAmount, minAmount }).toString()); }, [amount, maxAmount, minAmount]); const handleAmountAdd = (0, _react2.useCallback)(() => { setAmountValue(prevState => { const newAmount = (0, _amountControl.checkForValidAmount)({ amount: prevState + step, minAmount, maxAmount }); if (typeof onChange === 'function') { onChange(newAmount); } return typeof amount === 'number' ? prevState : newAmount; }); setInputValue(prevState => (0, _amountControl.checkForValidAmount)({ amount: Number(prevState) + step, minAmount, maxAmount }).toString()); }, [amount, maxAmount, minAmount, onChange, step]); const handleAmountRemove = (0, _react2.useCallback)(() => { if (displayState === 'default') { return; } setAmountValue(prevState => { const newAmount = (0, _amountControl.checkForValidAmount)({ amount: prevState - step, minAmount, maxAmount }); if (typeof onChange === 'function') { onChange(newAmount); } return newAmount; }); setInputValue(prevState => (0, _amountControl.checkForValidAmount)({ amount: Number(prevState) - step, minAmount, maxAmount }).toString()); }, [displayState, maxAmount, minAmount, onChange, step]); const handleFirstAmount = (0, _react2.useCallback)(() => { if (isDisabled) { return; } if (amountValue !== minAmount) { return; } if (typeof onChange === 'function') { onChange(minAmount + step); } setAmountValue(minAmount + step); setInputValue((minAmount + step).toString()); }, [amountValue, isDisabled, minAmount, onChange, step]); const handlePseudoInputClick = (0, _react2.useCallback)(() => { if (isDisabled) { return; } setIsEditing(true); window.requestAnimationFrame(() => { var _inputRef$current; (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus(); }); }, [isDisabled]); const handleInputBlur = (0, _react2.useCallback)(() => { const checkedValue = (0, _amountControl.checkForValidAmount)({ minAmount, maxAmount, amount: Math.round(Number(inputValue) / step) * step }); setAmountValue(checkedValue); setInputValue(checkedValue.toString()); setIsEditing(false); if (typeof onChange === 'function') { onChange(checkedValue); } if (inputValue === '') { setInputValue(minAmount.toString()); } }, [inputValue, maxAmount, minAmount, onChange, step]); const handleInputChange = (0, _react2.useCallback)(event => { const { value } = event.target; const valueBefore = Number(value.replace(/\D/g, '')); if (valueBefore < minAmount && minAmount === 0) { setInputValue('0'); return; } setInputValue(valueBefore === 0 ? '' : valueBefore.toString()); }, [minAmount]); let inputLabel = inputValue; if (typeof label === 'string' && (displayState === 'default' || shouldForceLabel)) { inputLabel = label; } const shouldShowPseudoInput = !isEditing && (inputValue === '0' || shouldForceLabel && typeof label === 'string' || inputLabel === label); return (0, _react2.useMemo)(() => /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledAmountControl, { onClick: handleFirstAmount, $isDisabled: isDisabled }, /*#__PURE__*/_react2.default.createElement(_react.AnimatePresence, { initial: false }, ['normal'].includes(displayState) && /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledMotionAmountControlButton, { $shouldShowKeyboardHighlighting: shouldShowKeyboardHighlighting, key: "left_button", initial: { width: 0, opacity: 0, padding: 0 }, animate: { width: 40, opacity: 1, padding: 0 }, exit: { width: 0, opacity: 0, padding: 0 }, transition: { duration: 0.2, type: 'tween' }, onClick: handleAmountRemove, disabled: isDisabled || amountValue !== 0 && amountValue <= minAmount, $isDisabled: isDisabled || amountValue !== 0 && amountValue <= minAmount }, /*#__PURE__*/_react2.default.createElement(_Icon.default, { icons: ['fa fa-minus'], size: 14, color: "white" }))), /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledInputWrapper, null, shouldShowPseudoInput ? /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledAmountControlPseudoInput, { onClick: handlePseudoInputClick, $shouldShowWideInput: shouldShowWideInput, $shouldShowRightIcon: !['maxAmount'].includes(displayState) }, inputLabel) : /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledAmountControlInput, { ref: inputRef, $displayState: displayState, $shouldShowIcon: shouldShowIcon, $shouldShowWideInput: shouldShowWideInput, $hasFocus: hasFocus, $shouldShowKeyboardHighlighting: shouldShowKeyboardHighlighting, disabled: isDisabled, onFocus: () => setIsEditing(true), onBlur: handleInputBlur, onChange: handleInputChange, value: inputLabel })), /*#__PURE__*/_react2.default.createElement(_react.AnimatePresence, { initial: false }, /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledMotionAmountControlButton, { $shouldShowKeyboardHighlighting: shouldShowKeyboardHighlighting, key: "right_button", initial: { width: 0, opacity: 0, padding: 0 }, animate: { width: 40, opacity: 1, padding: 0 }, exit: { width: 0, opacity: 0, padding: 0 }, transition: { duration: 0.2, type: 'tween' }, $color: displayState === 'maxAmount' ? 'rgb(32, 198, 90)' : undefined, onClick: displayState === 'maxAmount' ? handleAmountRemove : handleAmountAdd, disabled: isDisabled || (maxAmount ? amountValue >= maxAmount : false), $isDisabled: isDisabled || (maxAmount ? amountValue >= maxAmount : false) }, /*#__PURE__*/_react2.default.createElement(_Icon.default, { icons: !['normal'].includes(displayState) && icon ? [displayState === 'maxAmount' ? 'fa fa-check' : icon] : [displayState === 'maxAmount' ? 'fa fa-check' : 'fa fa-plus'], size: 14, color: iconColor ?? 'white' })))), [amountValue, displayState, handleAmountAdd, handleAmountRemove, handleFirstAmount, handleInputBlur, handleInputChange, handlePseudoInputClick, hasFocus, icon, iconColor, inputLabel, isDisabled, maxAmount, minAmount, shouldShowIcon, shouldShowKeyboardHighlighting, shouldShowPseudoInput, shouldShowWideInput]); }; AmountControl.displayName = 'AmountControl'; var _default = exports.default = AmountControl; //# sourceMappingURL=AmountControl.js.map