UNPKG

@chayns-components/core

Version:

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

283 lines (280 loc) • 10.2 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 _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, shouldShowAddIconOnMinAmount = false, shouldShowIcon = true, shouldShowWideInput = false, step: stepProp = 1 }) => { const [amountValue, setAmountValue] = (0, _react2.useState)(minAmount); const [inputValue, setInputValue] = (0, _react2.useState)(minAmount.toString()); const [displayState, setDisplayState] = (0, _react2.useState)('default'); 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 === 1 && amountValue === 1: setDisplayState('delete'); return; 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 (amountValue !== minAmount) { return; } if (typeof onChange === 'function') { onChange(minAmount + step); } setAmountValue(minAmount + step); setInputValue((minAmount + step).toString()); }, [amountValue, minAmount, onChange, step]); const handleDeleteIconClick = (0, _react2.useCallback)(() => { if (inputValue === '0') { window.setTimeout(() => { var _inputRef$current; (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus(); }, 500); } else { handleAmountRemove(); } }, [handleAmountRemove, inputValue]); const handleInputBlur = (0, _react2.useCallback)(() => { const checkedValue = (0, _amountControl.checkForValidAmount)({ minAmount, maxAmount, amount: Math.round(Number(inputValue) / step) * step }); setAmountValue(checkedValue); setInputValue(checkedValue.toString()); 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]); const leftIcon = (0, _react2.useMemo)(() => { let item = null; switch (displayState) { case 'default': item = /*#__PURE__*/_react2.default.createElement(_Icon.default, { icons: [icon ?? 'fa fa-cart-shopping'], size: 15, color: iconColor }); break; case 'delete': item = /*#__PURE__*/_react2.default.createElement(_Icon.default, { icons: ['fa ts-check'], size: 20, color: "white" }); break; case 'normal': item = /*#__PURE__*/_react2.default.createElement(_Icon.default, { icons: ['fa fa-minus'], size: 15, color: "red" }); break; case 'maxAmount': item = /*#__PURE__*/_react2.default.createElement(_Icon.default, { icons: ['fa fa-minus'], size: 15, color: "red" }); break; default: break; } return item; }, [displayState, icon, iconColor]); const shouldShowLeftIcon = (0, _react2.useMemo)(() => { if (shouldShowAddIconOnMinAmount && displayState === 'minAmount') { return false; } if (shouldShowIcon) { return true; } return !((displayState === 'default' || displayState === 'minAmount') && !shouldShowIcon); }, [displayState, shouldShowAddIconOnMinAmount, shouldShowIcon]); return (0, _react2.useMemo)(() => /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledAmountControl, { onClick: handleFirstAmount, $isDisabled: isDisabled }, /*#__PURE__*/_react2.default.createElement(_react.AnimatePresence, { initial: false }, shouldShowLeftIcon && /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledMotionAmountControlButton, { key: "right_button", initial: { width: 0, opacity: 0, padding: 0 }, animate: { width: displayState === 'normal' || displayState === 'maxAmount' ? 40 : 28, opacity: 1, padding: 0 }, exit: { width: 0, opacity: 0, padding: 0 }, $isWide: displayState === 'normal' || displayState === 'maxAmount', transition: { duration: 0.2, type: 'tween' }, onClick: handleAmountRemove, $color: displayState === 'delete' ? 'rgb(32, 198, 90)' : undefined, disabled: amountValue !== 0 && amountValue <= minAmount, $isDisabled: amountValue !== 0 && amountValue <= minAmount }, leftIcon)), displayState === 'delete' || inputValue === '0' ? /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledAmountControlPseudoInput, { onClick: handleDeleteIconClick, $shouldShowWideInput: shouldShowWideInput }, displayState === 'default' && label ? label : inputValue) : /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledAmountControlInput, { ref: inputRef, $displayState: displayState, $shouldShowIcon: shouldShowIcon, $shouldShowWideInput: shouldShowWideInput, $hasFocus: hasFocus, onBlur: handleInputBlur, onChange: handleInputChange, value: displayState === 'default' && label ? label : inputValue }), /*#__PURE__*/_react2.default.createElement(_react.AnimatePresence, { initial: false }, (displayState === 'normal' || displayState === 'minAmount') && /*#__PURE__*/_react2.default.createElement(_AmountControl.StyledMotionAmountControlButton, { 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' }, onClick: handleAmountAdd, $isWide: true, disabled: maxAmount ? amountValue >= maxAmount : false, $isDisabled: maxAmount ? amountValue >= maxAmount : false }, /*#__PURE__*/_react2.default.createElement(_Icon.default, { icons: ['fa fa-plus'], size: 15, color: "green" })))), [amountValue, displayState, handleAmountAdd, handleAmountRemove, handleDeleteIconClick, handleFirstAmount, handleInputBlur, handleInputChange, hasFocus, inputValue, isDisabled, label, leftIcon, maxAmount, minAmount, shouldShowIcon, shouldShowLeftIcon, shouldShowWideInput]); }; AmountControl.displayName = 'AmountControl'; var _default = exports.default = AmountControl; //# sourceMappingURL=AmountControl.js.map