@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
283 lines (280 loc) • 10.2 kB
JavaScript
"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